--- connectivity/source/drivers/postgresql/makefile.mk | 214 ++ .../source/drivers/postgresql/postgresql-sdbc.uno | 2 + .../source/drivers/postgresql/postgresql.xcu | 50 + .../source/drivers/postgresql/pq_allocator.hxx | 225 ++ .../source/drivers/postgresql/pq_array.cxx | 95 + .../source/drivers/postgresql/pq_array.hxx | 128 ++ .../source/drivers/postgresql/pq_baseresultset.cxx | 742 +++++++ .../source/drivers/postgresql/pq_baseresultset.hxx | 268 +++ .../source/drivers/postgresql/pq_connection.cxx | 740 +++++++ .../source/drivers/postgresql/pq_connection.hxx | 285 +++ .../drivers/postgresql/pq_databasemetadata.cxx | 2164 ++++++++++++++++++++ .../drivers/postgresql/pq_databasemetadata.hxx | 244 +++ .../source/drivers/postgresql/pq_driver.cxx | 406 ++++ .../source/drivers/postgresql/pq_driver.hxx | 161 ++ .../postgresql/pq_fakedupdateableresultset.cxx | 206 ++ .../postgresql/pq_fakedupdateableresultset.hxx | 133 ++ .../drivers/postgresql/pq_preparedstatement.cxx | 881 ++++++++ .../drivers/postgresql/pq_preparedstatement.hxx | 284 +++ .../source/drivers/postgresql/pq_resultset.cxx | 257 +++ .../source/drivers/postgresql/pq_resultset.hxx | 122 ++ .../drivers/postgresql/pq_resultsetmetadata.cxx | 523 +++++ .../drivers/postgresql/pq_resultsetmetadata.hxx | 156 ++ .../drivers/postgresql/pq_sequenceresultset.cxx | 150 ++ .../drivers/postgresql/pq_sequenceresultset.hxx | 130 ++ .../postgresql/pq_sequenceresultsetmetadata.cxx | 182 ++ .../postgresql/pq_sequenceresultsetmetadata.hxx | 53 + .../source/drivers/postgresql/pq_statement.cxx | 1063 ++++++++++ .../source/drivers/postgresql/pq_statement.hxx | 229 +++ .../source/drivers/postgresql/pq_statics.cxx | 758 +++++++ .../source/drivers/postgresql/pq_statics.hxx | 296 +++ .../source/drivers/postgresql/pq_tools.cxx | 1232 +++++++++++ .../source/drivers/postgresql/pq_tools.hxx | 201 ++ .../drivers/postgresql/pq_updateableresultset.cxx | 569 +++++ .../drivers/postgresql/pq_updateableresultset.hxx | 118 ++ .../source/drivers/postgresql/pq_xbase.cxx | 279 +++ .../source/drivers/postgresql/pq_xbase.hxx | 161 ++ .../source/drivers/postgresql/pq_xcolumn.cxx | 124 ++ .../source/drivers/postgresql/pq_xcolumn.hxx | 108 + .../source/drivers/postgresql/pq_xcolumns.cxx | 616 ++++++ .../source/drivers/postgresql/pq_xcolumns.hxx | 147 ++ .../source/drivers/postgresql/pq_xcontainer.cxx | 514 +++++ .../source/drivers/postgresql/pq_xcontainer.hxx | 240 +++ .../source/drivers/postgresql/pq_xindex.cxx | 267 +++ .../source/drivers/postgresql/pq_xindex.hxx | 156 ++ .../source/drivers/postgresql/pq_xindexcolumn.cxx | 122 ++ .../source/drivers/postgresql/pq_xindexcolumn.hxx | 109 + .../source/drivers/postgresql/pq_xindexcolumns.cxx | 322 +++ .../source/drivers/postgresql/pq_xindexcolumns.hxx | 146 ++ .../source/drivers/postgresql/pq_xindexes.cxx | 355 ++++ .../source/drivers/postgresql/pq_xindexes.hxx | 135 ++ connectivity/source/drivers/postgresql/pq_xkey.cxx | 262 +++ connectivity/source/drivers/postgresql/pq_xkey.hxx | 152 ++ .../source/drivers/postgresql/pq_xkeycolumn.cxx | 121 ++ .../source/drivers/postgresql/pq_xkeycolumn.hxx | 108 + .../source/drivers/postgresql/pq_xkeycolumns.cxx | 411 ++++ .../source/drivers/postgresql/pq_xkeycolumns.hxx | 134 ++ .../source/drivers/postgresql/pq_xkeys.cxx | 387 ++++ .../source/drivers/postgresql/pq_xkeys.hxx | 134 ++ .../source/drivers/postgresql/pq_xtable.cxx | 484 +++++ .../source/drivers/postgresql/pq_xtable.hxx | 220 ++ .../source/drivers/postgresql/pq_xtables.cxx | 464 +++++ .../source/drivers/postgresql/pq_xtables.hxx | 118 ++ .../source/drivers/postgresql/pq_xuser.cxx | 257 +++ .../source/drivers/postgresql/pq_xuser.hxx | 132 ++ .../source/drivers/postgresql/pq_xusers.cxx | 256 +++ .../source/drivers/postgresql/pq_xusers.hxx | 116 ++ .../source/drivers/postgresql/pq_xview.cxx | 285 +++ .../source/drivers/postgresql/pq_xview.hxx | 133 ++ .../source/drivers/postgresql/pq_xviews.cxx | 304 +++ .../source/drivers/postgresql/pq_xviews.hxx | 118 ++ 70 files changed, 21664 insertions(+), 0 deletions(-) create mode 100644 connectivity/source/drivers/postgresql/makefile.mk create mode 100644 connectivity/source/drivers/postgresql/postgresql-sdbc.uno create mode 100644 connectivity/source/drivers/postgresql/postgresql.xcu create mode 100644 connectivity/source/drivers/postgresql/pq_allocator.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_array.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_array.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_baseresultset.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_baseresultset.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_connection.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_connection.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_databasemetadata.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_databasemetadata.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_driver.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_driver.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_fakedupdateableresultset.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_fakedupdateableresultset.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_preparedstatement.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_preparedstatement.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_resultset.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_resultset.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_resultsetmetadata.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_resultsetmetadata.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_sequenceresultset.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_sequenceresultset.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_sequenceresultsetmetadata.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_sequenceresultsetmetadata.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_statement.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_statement.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_statics.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_statics.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_tools.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_tools.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_updateableresultset.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_updateableresultset.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xbase.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xbase.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xcolumn.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xcolumn.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xcolumns.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xcolumns.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xcontainer.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xcontainer.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xindex.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xindex.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xindexcolumn.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xindexcolumn.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xindexcolumns.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xindexcolumns.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xindexes.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xindexes.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xkey.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xkey.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xkeycolumn.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xkeycolumn.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xkeycolumns.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xkeycolumns.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xkeys.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xkeys.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xtable.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xtable.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xtables.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xtables.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xuser.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xuser.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xusers.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xusers.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xview.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xview.hxx create mode 100644 connectivity/source/drivers/postgresql/pq_xviews.cxx create mode 100644 connectivity/source/drivers/postgresql/pq_xviews.hxx diff --git connectivity/source/drivers/postgresql/makefile.mk connectivity/source/drivers/postgresql/makefile.mk new file mode 100644 index 0000000..1afe9c1 --- /dev/null +++ connectivity/source/drivers/postgresql/makefile.mk @@ -0,0 +1,214 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.2.15 $ +# +# last change: $Author: jbu $ $Date: 2010/02/07 12:31:34 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# 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 +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/..$/.. + +PRJNAME=postgresql +TARGET=postgresql +ENABLE_EXCEPTIONS=TRUE +LIBTARGET=NO +USE_DEFFILE=TRUE +NO_DEFAULT_STL=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.IF "$(SYSTEM_POSTGRESQL)" != "YES" +.INCLUDE : $(SOLARINCDIR)$/postgresql/postgresql-version.mk +.ENDIF +#------------------------------------------------------------------- + +# uno component naming scheme +DLLPRE= + +PQ_SDBC_MAJOR=0 +PQ_SDBC_MINOR=7 +PQ_SDBC_MICRO=6b +.IF "$(SYSTEM_POSTGRESQL)" == "YES" +POSTGRESQL_MAJOR=`pg_config --version | awk '{ print $$2 }' | cut -d. -f1` +POSTGRESQL_MINOR=`pg_config --version | awk '{ print $$2 }' | cut -d. -f2` +POSTGRESQL_MICRO=`pg_config --version | awk '{ print $$2 }' | cut -d. -f3` +.ENDIF + +.IF "$(SYSTEM_POSTGRESQL)" != "YES" +POSTGRESQL_INCLUDES=-I$(SOLARINCDIR)$/postgresql +.ELSE +POSTGRESQL_INCLUDES=-I`pg_config --includedir` +.ENDIF + +CFLAGS+=$(POSTGRESQL_INCLUDES) \ + -DPOSTGRESQL_MAJOR=$(POSTGRESQL_MAJOR) \ + -DPOSTGRESQL_MINOR=$(POSTGRESQL_MINOR) \ + -DPOSTGRESQL_MICRO=$(POSTGRESQL_MICRO) \ + -DPQ_SDBC_MAJOR=$(PQ_SDBC_MAJOR) \ + -DPQ_SDBC_MINOR=$(PQ_SDBC_MINOR) \ + -DPQ_SDBC_MICRO=$(PQ_SDBC_MICRO) + +SHL1TARGET=postgresql-sdbc.uno +LIB1TARGET=$(SLB)$/$(SHL1TARGET).lib +LIB1OBJFILES= \ + $(SLO)$/pq_driver.obj + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1LIBS= $(LIB1TARGET) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME= $(SHL1TARGET) +SHL1VERSIONMAP=$(SOLARENV)$/src$/component.map + +# use the static version +.IF "$(GUI)"=="WNT" +PQLIB=libpq.lib wsock32.lib advapi32.lib +.ELSE +PQLIB=-lpq -lcrypt +.ENDIF +SHL2TARGET=postgresql-sdbc-impl.uno +LIB2TARGET=$(SLB)$/$(SHL2TARGET).lib +LIB2OBJFILES= \ + $(SLO)$/pq_connection.obj \ + $(SLO)$/pq_statement.obj \ + $(SLO)$/pq_resultset.obj \ + $(SLO)$/pq_preparedstatement.obj \ + $(SLO)$/pq_resultsetmetadata.obj \ + $(SLO)$/pq_databasemetadata.obj \ + $(SLO)$/pq_sequenceresultset.obj \ + $(SLO)$/pq_baseresultset.obj \ + $(SLO)$/pq_statics.obj \ + $(SLO)$/pq_xtable.obj \ + $(SLO)$/pq_xcontainer.obj \ + $(SLO)$/pq_xbase.obj \ + $(SLO)$/pq_xtables.obj \ + $(SLO)$/pq_xcolumns.obj \ + $(SLO)$/pq_xcolumn.obj \ + $(SLO)$/pq_tools.obj \ + $(SLO)$/pq_xkey.obj \ + $(SLO)$/pq_xkeys.obj \ + $(SLO)$/pq_xkeycolumn.obj \ + $(SLO)$/pq_xkeycolumns.obj \ + $(SLO)$/pq_xuser.obj \ + $(SLO)$/pq_xusers.obj \ + $(SLO)$/pq_xview.obj \ + $(SLO)$/pq_xviews.obj \ + $(SLO)$/pq_xindex.obj \ + $(SLO)$/pq_xindexes.obj \ + $(SLO)$/pq_xindexcolumn.obj \ + $(SLO)$/pq_xindexcolumns.obj \ + $(SLO)$/pq_updateableresultset.obj \ + $(SLO)$/pq_fakedupdateableresultset.obj \ + $(SLO)$/pq_array.obj \ + $(SLO)$/pq_sequenceresultsetmetadata.obj + + +SHL2STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) \ + $(SALHELPERLIB) \ + $(PQLIB) + +SHL2LIBS= $(LIB2TARGET) +SHL2DEF= $(MISC)$/$(SHL2TARGET).def +DEF2NAME= $(SHL2TARGET) +SHL2VERSIONMAP=$(SOLARENV)$/src$/component.map + + +SLOFILES= $(LIB1OBJFILES) $(LIB2OBJFILES) + + +DRIVERNAME=postgresql-sdbc-$(PQ_SDBC_MAJOR).$(PQ_SDBC_MINOR).$(PQ_SDBC_MICRO).zip +ALLTAR : $(DLLDEST)$/$(DRIVERNAME) + +# --- Targets ------------------------------------------------------ +.INCLUDE : target.mk + +.IF "$(GUI)" == "UNX" +INI_EXT=rc +.ELSE +INI_EXT=.ini +.ENDIF + +$(DLLDEST)$/$(SHL1TARGET)$(INI_EXT): $(SHL1TARGET) + +cp $? $@ + + +$(DLLDEST)$/$(DRIVERNAME): \ + $(DLLDEST)$/postgresql.xcu \ + $(DLLDEST)$/$(SHL1TARGET)$(DLLPOST) \ + $(DLLDEST)$/$(SHL2TARGET)$(DLLPOST) \ + $(DLLDEST)$/$(SHL1TARGET)$(INI_EXT) + +cd $(DLLDEST) && \ + zip -r $(DRIVERNAME) \ + $(SHL1TARGET)$(DLLPOST) \ + $(SHL2TARGET)$(DLLPOST) \ + $(SHL1TARGET)$(INI_EXT) \ + postgresql.xcu + +$(DLLDEST)$/postgresql.xcu : postgresql.xcu + -rm -f $@ + cat postgresql.xcu > $@ + +strip : +.IF "$(GUI)"!="WNT" + strip $(DLLDEST)$/$(SHL1TARGET)$(DLLPOST) $(DLLDEST)$/$(SHL2TARGET)$(DLLPOST) +.ENDIF diff --git connectivity/source/drivers/postgresql/postgresql-sdbc.uno connectivity/source/drivers/postgresql/postgresql-sdbc.uno new file mode 100644 index 0000000..8d51ca2 --- /dev/null +++ connectivity/source/drivers/postgresql/postgresql-sdbc.uno @@ -0,0 +1,2 @@ +[Bootstrap] +PQ_LOGLEVEL=NONE diff --git connectivity/source/drivers/postgresql/postgresql.xcu connectivity/source/drivers/postgresql/postgresql.xcu new file mode 100644 index 0000000..3f3c93c --- /dev/null +++ connectivity/source/drivers/postgresql/postgresql.xcu @@ -0,0 +1,50 @@ + + + + + + + org.openoffice.comp.connectivity.pq.Driver + + + postgresql + + + + + + + + + UserPassword + + + + + + diff --git connectivity/source/drivers/postgresql/pq_allocator.hxx connectivity/source/drivers/postgresql/pq_allocator.hxx new file mode 100644 index 0000000..d03b424 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_allocator.hxx @@ -0,0 +1,225 @@ +/************************************************************************* + * + * $RCSfile: pq_allocator.hxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2007/08/28 21:24:00 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2002 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _PQ_ALLOCATOR_ +#define _PQ_ALLOCATOR_ + +#include +#include "sal/types.h" + +/** jbu: This source has been copied from sal/inc/internal/allocator.hxx, + because it is not a public interface. Thx a lot for figuring this + out. + */ + +//###################################################### +// This is no general purpose STL allocator but one +// necessary to use STL for some implementation but +// avoid linking sal against the STLPort library!!! +// For more information on when and how to define a +// custom stl allocator have a look at Scott Meyers: +// "Effective STL", Nicolai M. Josuttis: +// "The C++ Standard Library - A Tutorial and Reference" +// and at http://www.josuttis.com/cppcode/allocator.html + +namespace pq_sdbc_driver { + +template +class Allocator +{ +public: + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef ::std::size_t size_type; + typedef ::std::ptrdiff_t difference_type; + + //----------------------------------------- + template + struct rebind + { + typedef Allocator other; + }; + + //----------------------------------------- + pointer address (reference value) const + { + return &value; + } + + //----------------------------------------- + const_pointer address (const_reference value) const + { + return &value; + } + + //----------------------------------------- + Allocator() SAL_THROW(()) + {} + + //----------------------------------------- + template + Allocator (const Allocator&) SAL_THROW(()) + {} + + //----------------------------------------- + Allocator(const Allocator&) SAL_THROW(()) + {} + + //----------------------------------------- + ~Allocator() SAL_THROW(()) + {} + + //----------------------------------------- + size_type max_size() const SAL_THROW(()) + { + return size_type(-1)/sizeof(T); + } + + //----------------------------------------- + /* Normally the code for allocate should + throw a std::bad_alloc exception if the + requested memory could not be allocated: + (C++ standard 20.4.1.1): + + pointer allocate (size_type n, const void* hint = 0) + { + pointer p = reinterpret_cast( + rtl_allocateMemory(sal_uInt32(n * sizeof(T)))); + + if (NULL == p) + throw ::std::bad_alloc(); + + return p; + } + + but some compilers do not compile it if exceptions + are not enabled, e.g. GCC under Linux and it is + in general not desired to compile sal with exceptions + enabled. */ + pointer allocate (size_type n, const void* hint = 0) + { + return reinterpret_cast( + rtl_allocateMemory(sal_uInt32(n * sizeof(T)))); + } + + //----------------------------------------- + void deallocate (pointer p, size_type n) + { + rtl_freeMemory(p); + } + + //----------------------------------------- + void construct (pointer p, const T& value) + { + new ((void*)p)T(value); + } + + //----------------------------------------- + void destroy (pointer p) + { + p->~T(); + } +}; + +//###################################################### +// Custom STL allocators must be stateless (see +// references above) that's why the operators below +// return always true or false +template +inline bool operator== (const Allocator&, const Allocator&) SAL_THROW(()) +{ + return true; +} + +template +inline bool operator!= (const Allocator&, const Allocator&) SAL_THROW(()) +{ + return false; +} + +} /* namespace sal */ + +//###################################################### +/* REQUIRED BY STLPort (see stlport '_alloc.h'): + Hack for compilers that do not support member + template classes (e.g. MSVC 6) */ +#if defined (_MSC_VER) +#if (_MSC_VER < 1400) // MSVC 6 +namespace _STL +{ +#endif +#endif + template + inline pq_sdbc_driver::Allocator & __stl_alloc_rebind ( + pq_sdbc_driver::Allocator & a, U const *) + { + return (pq_sdbc_driver::Allocator&)(a); + } +#if defined (_MSC_VER) +#if (_MSC_VER < 1400) // MSVC 6 +} +#endif +#endif + +#endif /* INCLUDED_SAL_INTERNAL_ALLOCATOR_HXX */ diff --git connectivity/source/drivers/postgresql/pq_array.cxx connectivity/source/drivers/postgresql/pq_array.cxx new file mode 100644 index 0000000..b798d40 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_array.cxx @@ -0,0 +1,95 @@ +#include + +#include +#include + + +#include "pq_array.hxx" +#include "pq_statics.hxx" +#include "pq_sequenceresultset.hxx" + +using rtl::OUString; + +using com::sun::star::sdbc::SQLException; +using com::sun::star::uno::Any; + +using com::sun::star::uno::Sequence; +namespace pq_sdbc_driver +{ + + +::rtl::OUString Array::getBaseTypeName( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "varchar" ) ); +} + +sal_Int32 Array::getBaseType( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return com::sun::star::sdbc::DataType::VARCHAR; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > Array::getArray( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return m_data; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > Array::getArrayAtIndex( + sal_Int32 index, + sal_Int32 count, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + checkRange( index, count ); + return Sequence< Any > ( &m_data[index-1], count ); +} + +::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > Array::getResultSet( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return getResultSetAtIndex( 0 , m_data.getLength() , typeMap ); +} + +::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > Array::getResultSetAtIndex( + sal_Int32 index, + sal_Int32 count, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + checkRange( index, count ); + Sequence< Sequence< Any > > ret( count ); + + for( int i = 0 ; i < count ; i ++ ) + { + Sequence< Any > row( 2 ); + row[0] <<= (sal_Int32) ( i + index ); + row[1] = m_data[i+index-1]; + ret[i] = row; + } + + return new SequenceResultSet( + m_refMutex, m_owner, getStatics().resultSetArrayColumnNames, ret, m_tc ); +} + + +void Array::checkRange( sal_Int32 index, sal_Int32 count ) +{ + if( index >= 1 && index -1 + count <= m_data.getLength() ) + return; + rtl::OUStringBuffer buf; + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Array::getArrayAtIndex(): allowed range for index + count " ) ); + buf.append( m_data.getLength() ); + buf.appendAscii( ", got " ); + buf.append( index ); + buf.appendAscii( " + " ); + buf.append( count ); + + throw SQLException( buf.makeStringAndClear() , *this, rtl::OUString(), 1, Any()); + +} + +} diff --git connectivity/source/drivers/postgresql/pq_array.hxx connectivity/source/drivers/postgresql/pq_array.hxx new file mode 100644 index 0000000..d008ac2 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_array.hxx @@ -0,0 +1,128 @@ +/************************************************************************* + * + * $RCSfile: pq_array.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/08/29 08:33:28 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_ARRAY_HXX +#define HEADER_PQ_ARRAY_HXX +#include +#include + +#include "pq_connection.hxx" + +namespace pq_sdbc_driver +{ + +class Array : public cppu::WeakImplHelper1< com::sun::star::sdbc::XArray > +{ + com::sun::star::uno::Sequence< com::sun::star::uno::Any > m_data; + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > m_owner; + com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter > m_tc; + rtl::Reference< RefCountedMutex > m_refMutex; + +public: + Array( + const rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & data, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > & owner, + const com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter > &tc) : + m_refMutex( mutex ), + m_data( data ), + m_owner( owner ), + m_tc( tc ) + {} + +public: // XArray + + // Methods + virtual ::rtl::OUString SAL_CALL getBaseTypeName( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getBaseType( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getArray( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getArrayAtIndex( + sal_Int32 index, + sal_Int32 count, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL + getResultSet( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getResultSetAtIndex( + sal_Int32 index, + sal_Int32 count, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +private: + void checkRange( sal_Int32 index, sal_Int32 count ); +}; + + +}; + +#endif diff --git connectivity/source/drivers/postgresql/pq_baseresultset.cxx connectivity/source/drivers/postgresql/pq_baseresultset.cxx new file mode 100644 index 0000000..aca40d7 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_baseresultset.cxx @@ -0,0 +1,742 @@ +/************************************************************************* + * + * $RCSfile: pq_baseresultset.cxx,v $ + * + * $Revision: 1.1.2.4 $ + * + * last change: $Author: jbu $ $Date: 2004/08/29 08:33:28 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include + +#include +#include + +#include "pq_tools.hxx" +#include "pq_array.hxx" +#include "pq_statement.hxx" +#include "pq_baseresultset.hxx" +#include "pq_resultsetmetadata.hxx" + +#include + +using osl::Mutex; +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringToOString; +using rtl::OUStringBuffer; +using rtl::OString; + +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::XMultiPropertySet; +using com::sun::star::beans::XFastPropertySet; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Exception; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; + +using com::sun::star::lang::IllegalArgumentException; + +using com::sun::star::sdbc::XWarningsSupplier; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XConnection; +using com::sun::star::sdbc::SQLException; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XColumnLocate; +using com::sun::star::sdbc::XResultSetMetaData; +using com::sun::star::sdbc::XResultSetMetaDataSupplier; + + +using com::sun::star::beans::Property; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +static ::cppu::IPropertyArrayHelper & getResultSetPropertyArrayHelper() +{ + static ::cppu::IPropertyArrayHelper *pArrayHelper; + if( ! pArrayHelper ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pArrayHelper ) + { + static Property aTable[] = + { + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("CursorName") ), 0, + ::getCppuType( (OUString *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("EscapeProcessing") ), 0, + ::getBooleanCppuType() , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("FetchDirection") ), 0, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("FetchSize") ), 0, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetConcurrency") ), 0, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetType") ), 0, + ::getCppuType( (sal_Int32 *)0) , 0 ) + }; + OSL_ASSERT( sizeof(aTable) / sizeof(Property) == BASERESULTSET_SIZE ); + static ::cppu::OPropertyArrayHelper arrayHelper( aTable, BASERESULTSET_SIZE, sal_True ); + pArrayHelper = &arrayHelper; + } + } + return *pArrayHelper; +} + +BaseResultSet::BaseResultSet( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< XInterface > & owner, + sal_Int32 rowCount, + sal_Int32 colCount, + const Reference< com::sun::star::script::XTypeConverter > & tc ) + : OComponentHelper( refMutex->mutex ), + OPropertySetHelper( OComponentHelper::rBHelper ), + m_refMutex( refMutex ), + m_owner( owner ), + m_row( -1 ), + m_rowCount( rowCount ), + m_fieldCount( colCount ), + m_tc( tc ) +{ + POSTGRE_TRACE( "ctor BaseResultSet" ); +} + +BaseResultSet::~BaseResultSet() +{ + POSTGRE_TRACE( "dtor BaseResultSet" ); +} + +Any BaseResultSet::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = OComponentHelper::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( reqType, + static_cast< XResultSet * > ( this ), + static_cast< XResultSetMetaDataSupplier * > ( this ), + static_cast< XRow * > ( this ), + static_cast< XColumnLocate * > ( this ), + static_cast< XCloseable * > ( this ), + static_cast< XPropertySet * > ( this ), + static_cast< XMultiPropertySet * > ( this ), + static_cast< XFastPropertySet * > ( this ) ); + return ret; +} + +// void BaseResultSet::close( ) throw (SQLException, RuntimeException) +// { +// Reference< XInterface > owner; +// { +// ResultSetGuard guard(*this); +// if( m_result ) +// { +// PQclear(m_result ); +// m_result = 0; +// m_row = -1; +// } +// owner = m_owner; +// m_owner.clear(); +// } +// } + +Sequence BaseResultSet::getTypes() throw( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< XResultSet> *) 0 ), + getCppuType( (Reference< XResultSetMetaDataSupplier> *) 0 ), + getCppuType( (Reference< XRow> *) 0 ), + getCppuType( (Reference< XColumnLocate> *) 0 ), + getCppuType( (Reference< XCloseable> *) 0 ), + getCppuType( (Reference< XPropertySet >*) 0 ), + getCppuType( (Reference< XFastPropertySet > *) 0 ), + getCppuType( (Reference< XMultiPropertySet > *) 0 ), + OComponentHelper::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> BaseResultSet::getImplementationId() throw( RuntimeException ) +{ + static cppu::OImplementationId *pId; + if( ! pId ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( ! pId ) + { + static cppu::OImplementationId id(sal_False); + pId = &id; + } + } + return pId->getImplementationId(); +} + +// Reference< XResultSetMetaData > BaseResultSet::getMetaData( ) throw (SQLException, RuntimeException) +// { +// ResultSetGuard guard(*this); +// checkClosed(); +// return new ResultSetMetaData( m_refMutex, this, &m_result ); +// } + +sal_Bool BaseResultSet::next( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + m_row ++; + return m_row < m_rowCount; +} + +sal_Bool BaseResultSet::isBeforeFirst( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return m_row == -1; +} + +sal_Bool BaseResultSet::isAfterLast( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return m_row >= m_rowCount; +} + +sal_Bool BaseResultSet::isFirst( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return m_row == 0 && m_rowCount; +} + +sal_Bool BaseResultSet::isLast( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return m_row >= 0 && m_row + 1 == m_rowCount; +} + +void BaseResultSet::beforeFirst( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + m_row = -1; +} + +void BaseResultSet::afterLast( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + m_row = m_rowCount; +} + +sal_Bool BaseResultSet::first( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + sal_Bool bRet = ( m_rowCount > 0 ); + if( bRet ) + m_row = 0; + return bRet; +} + +sal_Bool BaseResultSet::last( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + sal_Bool bRet = ( m_rowCount > 0 ); + if( bRet ) + m_row = m_rowCount -1; + return bRet; +} + +sal_Int32 BaseResultSet::getRow( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return m_row +1; +} + +sal_Bool BaseResultSet::absolute( sal_Int32 row ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + if( row > 0 ) + { + m_row = row -1; + if( m_row > m_rowCount ) + m_row = m_rowCount; + } + else + { + m_row = m_rowCount + row; + if( m_row < -1 ) + m_row = -1; + } + return sal_True; +} + +sal_Bool BaseResultSet::relative( sal_Int32 rows ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + m_row += rows; + + if( m_row > m_rowCount ) + m_row = m_rowCount; + else if ( m_row < -1 ) + m_row = -1; + return sal_True; +} + +sal_Bool BaseResultSet::previous( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + sal_Bool bRet = ( m_row != -1 ); + if( bRet ) + m_row --; + return bRet; +} + +void BaseResultSet::refreshRow( ) throw (SQLException, RuntimeException) +{ + // TODO: not supported for now +} + +sal_Bool BaseResultSet::rowUpdated( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool BaseResultSet::rowInserted( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool BaseResultSet::rowDeleted( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +Reference< XInterface > BaseResultSet::getStatement() throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return m_owner; +} + + +//----------------- XRow interface ---------------------------------------------------- + +sal_Bool BaseResultSet::wasNull( ) throw (SQLException, RuntimeException) +{ + return m_wasNull; +} + +Any BaseResultSet::convertTo( const Any & val , const Type & type ) +{ + Any aRet; + try + { + aRet = m_tc->convertTo( val , type ); + } + catch( com::sun::star::lang::IllegalArgumentException & e ) + {} + catch( com::sun::star::script::CannotConvertException & e ) + {} + return aRet; +} + +sal_Bool BaseResultSet::getBoolean( sal_Int32 columnIndex ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( columnIndex ); + checkRowIndex( sal_True /* must be on row */ ); + + sal_Bool b = sal_False; + + OUString str = getString( columnIndex ); + + if( str.getLength() > 0 ) + { + switch(str[0]) + { + case '1': + case 't': + case 'T': + case 'y': + case 'Y': + + return sal_True; + } + } + return sal_False; +} + +sal_Int8 BaseResultSet::getByte( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( columnIndex ); + checkRowIndex( sal_True /* must be on row */ ); + sal_Int8 b = 0; + convertTo( getValue( columnIndex ), getCppuType( &b )) >>= b; + return b; +} + +sal_Int16 BaseResultSet::getShort( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( columnIndex ); + checkRowIndex( sal_True /* must be on row */ ); + sal_Int16 i = 0; + convertTo( getValue( columnIndex ), getCppuType( &i )) >>= i; + return i; +} + +OUString BaseResultSet::getString( sal_Int32 columnIndex ) throw (SQLException, RuntimeException) +{ + MutexGuard guard(m_refMutex->mutex); + checkClosed(); + checkColumnIndex( columnIndex ); + checkRowIndex( sal_True /* must be on row */ ); + OUString ret; + convertTo( getValue( columnIndex ), getCppuType( &ret ) ) >>= ret; +// printf( "BaseResultSet::getString() %s\n" , OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ).getStr() ); + return ret; +} + +sal_Int32 BaseResultSet::getInt( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( columnIndex ); + checkRowIndex( sal_True /* must be on row */ ); + sal_Int32 i = 0; + convertTo( getValue( columnIndex ), getCppuType( &i )) >>= i; + return i; +} + +sal_Int64 BaseResultSet::getLong( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( columnIndex ); + checkRowIndex( sal_True /* must be on row */ ); + sal_Int64 i = 0; + convertTo( getValue( columnIndex ), getCppuType( &i )) >>= i; + return i; +} + +float BaseResultSet::getFloat( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( columnIndex ); + checkRowIndex( sal_True /* must be on row */ ); + float f = 0.; + convertTo( getValue( columnIndex ), getCppuType( &f )) >>= f; + return f; +} + +double BaseResultSet::getDouble( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( columnIndex ); + double d = 0.; + convertTo( getValue( columnIndex ), getCppuType( &d )) >>= d; + return d; +} + +Sequence< sal_Int8 > BaseResultSet::getBytes( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( columnIndex ); + checkRowIndex( sal_True /* must be on row */ ); + + Sequence< sal_Int8 > ret; + OUString ustr; + if( ! (getValue( columnIndex ) >>= ustr) ) + m_wasNull = true; + else + { + // if this is a binary, it must contain escaped data ! + OString val = rtl::OUStringToOString( ustr, RTL_TEXTENCODING_ASCII_US ); + + size_t length; + char * res = (char*) PQunescapeBytea( (unsigned char *)val.getStr() , &length); + ret = Sequence< sal_Int8 > ( (sal_Int8*)res, length ); + if( res ) + free( res ); + } + return ret; +} + + +::com::sun::star::util::Date BaseResultSet::getDate( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + return string2Date( getString( columnIndex ) ); +} + +::com::sun::star::util::Time BaseResultSet::getTime( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + return string2Time( getString( columnIndex ) ); +} + +::com::sun::star::util::DateTime BaseResultSet::getTimestamp( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + return string2DateTime( getString( columnIndex ) ); +} + +Reference< ::com::sun::star::io::XInputStream > BaseResultSet::getBinaryStream( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + return 0; +} + +Reference< ::com::sun::star::io::XInputStream > BaseResultSet::getCharacterStream( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + return 0; +} + +Any BaseResultSet::getObject( + sal_Int32 columnIndex, + const Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (SQLException, RuntimeException) +{ + return Any(); +} + +Reference< ::com::sun::star::sdbc::XRef > BaseResultSet::getRef( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + return Reference< com::sun::star::sdbc::XRef > (); +} + +Reference< ::com::sun::star::sdbc::XBlob > BaseResultSet::getBlob( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + return Reference< com::sun::star::sdbc::XBlob > (); +} + +Reference< ::com::sun::star::sdbc::XClob > BaseResultSet::getClob( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + return Reference< com::sun::star::sdbc::XClob > (); +} + +Reference< ::com::sun::star::sdbc::XArray > BaseResultSet::getArray( sal_Int32 columnIndex ) + throw (SQLException, RuntimeException) +{ + return new Array( m_refMutex, parseArray( getString( columnIndex ) ), *this, m_tc ); +} + + +::cppu::IPropertyArrayHelper & BaseResultSet::getInfoHelper() +{ + return getResultSetPropertyArrayHelper(); +} + + +sal_Bool BaseResultSet::convertFastPropertyValue( + Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) + throw (IllegalArgumentException) +{ + sal_Bool bRet; + switch( nHandle ) + { + case BASERESULTSET_CURSOR_NAME: + { + OUString val; + bRet = ( rValue >>= val ); + m_props[nHandle] = makeAny( val ); + break; + } + case BASERESULTSET_ESCAPE_PROCESSING: + { + sal_Bool val; + bRet = ( rValue >>= val ); + m_props[nHandle] = makeAny( val ); + break; + } + case BASERESULTSET_FETCH_DIRECTION: + case BASERESULTSET_FETCH_SIZE: + case BASERESULTSET_RESULT_SET_CONCURRENCY: + case BASERESULTSET_RESULT_SET_TYPE: + { + sal_Int32 val; + bRet = ( rValue >>= val ); + m_props[nHandle] = makeAny( val ); + break; + } + default: + { + OUStringBuffer buf(128); + buf.appendAscii( "pq_resultset: Invalid property handle (" ); + buf.append( nHandle ); + buf.appendAscii( ")" ); + throw IllegalArgumentException( buf.makeStringAndClear(), *this, 2 ); + } + } + return bRet; +} + + +void BaseResultSet::setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle,const Any& rValue ) throw (Exception) +{ + m_props[nHandle] = rValue; +} + +void BaseResultSet::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const +{ + rValue = m_props[nHandle]; +} + +Reference < XPropertySetInfo > BaseResultSet::getPropertySetInfo() + throw(RuntimeException) +{ + return OPropertySetHelper::createPropertySetInfo( getResultSetPropertyArrayHelper() ); +} + +void BaseResultSet::disposing() +{ + close(); +} + +void BaseResultSet::checkColumnIndex(sal_Int32 index ) throw ( SQLException, RuntimeException ) +{ + if( index < 1 || index > m_fieldCount ) + { + OUStringBuffer buf(128); + buf.appendAscii( "pq_resultset: index out of range (" ); + buf.append( index ); + buf.appendAscii( ", allowed range is 1 to " ); + buf.append( m_fieldCount ); + buf.appendAscii( ")" ); + throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any() ); + } + +} + +void BaseResultSet::checkRowIndex( sal_Bool mustBeOnValidRow ) +{ + OUStringBuffer buf( 128 ); + buf.appendAscii( "pq_baseresultset: row index out of range, allowed is " ); + if( mustBeOnValidRow ) + { + if( m_row < 0 || m_row >= m_rowCount ) + { + buf.appendAscii( "0 to " ); + buf.append( ((sal_Int32)(m_rowCount -1)) ); + buf.appendAscii( ", got " ); + buf.append( m_row ); + throw SQLException( buf.makeStringAndClear(), *this, OUString(),1, Any() ); + } + } + else + { + if( m_row < -1 || m_row > m_rowCount ) + { + buf.appendAscii( "-1 to " ); + buf.append( m_rowCount ); + buf.appendAscii( ", got " ); + buf.append( m_row ); + throw SQLException( buf.makeStringAndClear(), *this, OUString(),1, Any() ); + } + } +} + +} diff --git connectivity/source/drivers/postgresql/pq_baseresultset.hxx connectivity/source/drivers/postgresql/pq_baseresultset.hxx new file mode 100644 index 0000000..d3a4f8b --- /dev/null +++ connectivity/source/drivers/postgresql/pq_baseresultset.hxx @@ -0,0 +1,268 @@ +/************************************************************************* + * + * $RCSfile: pq_baseresultset.hxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2007/08/26 20:40:40 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PG_BASERESULTSET_HXX_ +#define _PG_BASERESULTSET_HXX_ + +#include +#include + +#include +#include +#include +#include +#include "pq_connection.hxx" + +namespace pq_sdbc_driver +{ + +static const sal_Int32 BASERESULTSET_CURSOR_NAME = 0; +static const sal_Int32 BASERESULTSET_ESCAPE_PROCESSING = 1; +static const sal_Int32 BASERESULTSET_FETCH_DIRECTION = 2; +static const sal_Int32 BASERESULTSET_FETCH_SIZE = 3; +static const sal_Int32 BASERESULTSET_RESULT_SET_CONCURRENCY = 4; +static const sal_Int32 BASERESULTSET_RESULT_SET_TYPE = 5; + +#define BASERESULTSET_SIZE 6 + +class BaseResultSet : public cppu::OComponentHelper, + public cppu::OPropertySetHelper, + public com::sun::star::sdbc::XCloseable, + public com::sun::star::sdbc::XResultSetMetaDataSupplier, + public com::sun::star::sdbc::XResultSet, + public com::sun::star::sdbc::XRow, + public com::sun::star::sdbc::XColumnLocate +{ +protected: + com::sun::star::uno::Any m_props[BASERESULTSET_SIZE]; + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > m_owner; + com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter > m_tc; + ::rtl::Reference< RefCountedMutex > m_refMutex; + sal_Int32 m_row; + sal_Int32 m_rowCount; + sal_Int32 m_fieldCount; + sal_Bool m_wasNull; + +public: + inline cppu::OBroadcastHelper & getRBHelper() { return OComponentHelper::rBHelper;} + +protected: + /** mutex should be locked before called + */ + virtual void checkClosed() + throw ( com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException ) = 0; + virtual void checkColumnIndex( sal_Int32 index ) + throw ( com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException ); + virtual void checkRowIndex( sal_Bool mustBeOnValidRow ); + + virtual ::com::sun::star::uno::Any getValue( sal_Int32 columnIndex ) = 0; + com::sun::star::uno::Any convertTo( + const ::com::sun::star::uno::Any &str, const com::sun::star::uno::Type &type ); + +protected: + BaseResultSet( + const ::rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner, + sal_Int32 rowCount, + sal_Int32 columnCount, + const ::com::sun::star::uno::Reference< ::com::sun::star::script::XTypeConverter > &tc ); + ~BaseResultSet(); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XCloseable +// virtual void SAL_CALL close( ) +// throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0; + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XResultSetMetaDataSupplier +// virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL getMetaData( ) +// throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0; + +public: // XResultSet + // Methods + virtual sal_Bool SAL_CALL next( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isBeforeFirst( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isAfterLast( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isFirst( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isLast( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL beforeFirst( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL afterLast( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL first( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL last( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getRow( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL absolute( sal_Int32 row ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL relative( sal_Int32 rows ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL previous( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL refreshRow( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL rowUpdated( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL rowInserted( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL rowDeleted( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getStatement() + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + +public: // XRow + virtual sal_Bool SAL_CALL wasNull( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getString( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL getBoolean( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int8 SAL_CALL getByte( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getShort( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getInt( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getLong( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual float SAL_CALL getFloat( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL getDouble( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getBytes( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::util::Date SAL_CALL getDate( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::util::Time SAL_CALL getTime( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::util::DateTime SAL_CALL getTimestamp( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getBinaryStream( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getCharacterStream( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getObject( + sal_Int32 columnIndex, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef > SAL_CALL getRef( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob > SAL_CALL getBlob( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob > SAL_CALL getClob( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray > SAL_CALL getArray( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XColumnLocate +// virtual sal_Int32 SAL_CALL findColumn( const ::rtl::OUString& columnName ) +// throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0; + +public: // OPropertySetHelper + virtual cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper(); + + virtual sal_Bool SAL_CALL convertFastPropertyValue( + ::com::sun::star::uno::Any & rConvertedValue, + ::com::sun::star::uno::Any & rOldValue, + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::lang::IllegalArgumentException); + + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::uno::Exception); + + virtual void SAL_CALL getFastPropertyValue( + ::com::sun::star::uno::Any& rValue, + sal_Int32 nHandle ) const; + + // XPropertySet + ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw(com::sun::star::uno::RuntimeException); + +public: // OComponentHelper + virtual void SAL_CALL disposing(); + + +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_connection.cxx connectivity/source/drivers/postgresql/pq_connection.cxx new file mode 100644 index 0000000..a3a0f58 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_connection.cxx @@ -0,0 +1,740 @@ +/************************************************************************* + * + * $RCSfile: pq_connection.cxx,v $ + * + * $Revision: 1.1.2.5 $ + * + * last change: $Author: jbu $ $Date: 2007/01/07 13:50:37 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include +#include +#include +#include + +#include "pq_connection.hxx" +#include "pq_statement.hxx" +#include "pq_preparedstatement.hxx" +#include "pq_databasemetadata.hxx" +#include "pq_xcontainer.hxx" +#include "pq_statics.hxx" +#include "pq_xtables.hxx" +#include "pq_xviews.hxx" +#include "pq_xusers.hxx" + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +using rtl::OUStringBuffer; +using rtl::OUString; +using rtl::OString; +using rtl::OStringBuffer; +using rtl::OUStringToOString; +using osl::MutexGuard; + +using com::sun::star::container::XNameAccess; + +using com::sun::star::lang::XComponent; +using com::sun::star::lang::XInitialization; +using com::sun::star::lang::IllegalArgumentException; + +using com::sun::star::script::XTypeConverter; + +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Exception; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::XComponentContext; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; + +using com::sun::star::beans::PropertyValue; +using com::sun::star::beans::XPropertySet; + +using com::sun::star::sdbc::XConnection; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::SQLException; +using com::sun::star::sdbc::XWarningsSupplier; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XDatabaseMetaData; + +namespace pq_sdbc_driver +{ + +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + + +// ______________________________________________________________________________ +// Helper class for statement lifetime management +class ClosableReference : public cppu::WeakImplHelper1< com::sun::star::uno::XReference > +{ + Connection *m_conn; + ::rtl::ByteSequence m_id; +public: + ClosableReference( const ::rtl::ByteSequence & id , Connection *that ) + : m_id( id ), m_conn( that ) + { + that->acquire(); + } + + virtual ~ClosableReference() + { + if( m_conn ) + m_conn->release(); + } + + virtual void SAL_CALL dispose() throw () + { + if( m_conn ) + { + m_conn->removeFromWeakMap(m_id); + m_conn->release(); + m_conn = 0; + } + } +}; + +OUString ConnectionGetImplementationName() +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.connectivity.pq.Connection" ) ); +} +com::sun::star::uno::Sequence ConnectionGetSupportedServiceNames(void) +{ + OUString serv( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.Connection" ) ); + return Sequence< OUString> (&serv,1); +} + +static sal_Int32 readLogLevelFromConfiguration() +{ + sal_Int32 loglevel = LogLevel::NONE; + OUString fileName; + osl_getModuleURLFromAddress( + (void*) readLogLevelFromConfiguration, (rtl_uString **) &fileName ); + fileName = OUString( fileName.getStr(), fileName.lastIndexOf( '/' )+1 ); + fileName += OUString::createFromAscii( SAL_CONFIGFILE("postgresql-sdbc.uno") ); + rtl::Bootstrap bootstrapHandle( fileName ); + + OUString str; + if( bootstrapHandle.getFrom( ASCII_STR( "PQ_LOGLEVEL" ), str ) ) + { + if( str.equalsAscii( "NONE" ) ) + loglevel = LogLevel::NONE; + else if( str.equalsAscii( "ERROR" ) ) + loglevel = LogLevel::ERROR; + else if( str.equalsAscii( "SQL" ) ) + loglevel = LogLevel::SQL; + else if( str.equalsAscii( "INFO" ) ) + loglevel = LogLevel::SQL; + else + { + fprintf( stderr, "unknown loglevel %s\n", + OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + return loglevel; +} + +Connection::Connection( + const rtl::Reference< RefCountedMutex > &refMutex, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & ctx ) + : ConnectionBase( refMutex->mutex ), + m_ctx( ctx ) , + m_refMutex( refMutex ) +{ + m_settings.loglevel = readLogLevelFromConfiguration(); + + if( m_settings.loglevel > LogLevel::NONE ) + { + m_settings.logFile = fopen( "sdbc-pqsql.log", "a" ); + if( m_settings.logFile ) + { + setvbuf( m_settings.logFile, 0, _IONBF, 0 ); + log( &m_settings, m_settings.loglevel , "set this loglevel" ); + } + else + { + fprintf( stderr, "Couldn't open sdbc-pqsql.log file\n" ); + } + } +} + +Connection::~Connection() +{ + POSTGRE_TRACE( "dtor connection" ); + if( m_settings.pConnection ) + { + PQfinish( m_settings.pConnection ); + m_settings.pConnection = 0; + } + if( m_settings.logFile ) + { + fclose( m_settings.logFile ); + m_settings.logFile = 0; + } +} +typedef ::std::list< ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XCloseable > , + ::pq_sdbc_driver::Allocator < ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XCloseable > > > CloseableList; + +typedef ::std::list< ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > , + ::pq_sdbc_driver::Allocator < ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > > > DisposeableList; + +void Connection::close() throw ( SQLException, RuntimeException ) +{ + CloseableList lst; + DisposeableList lstDispose; + { + MutexGuard guard( m_refMutex->mutex ); + // silently ignore, if the connection has been closed already + if( m_settings.pConnection ) + { + log( &m_settings, LogLevel::INFO, "closing connection" ); + PQfinish( m_settings.pConnection ); + m_settings.pConnection = 0; + } + + lstDispose.push_back( Reference< XComponent > ( m_settings.users, UNO_QUERY ) ); + lstDispose.push_back( Reference< XComponent > ( m_settings.tables , UNO_QUERY ) ); + lstDispose.push_back( Reference< XComponent > ( m_meta, UNO_QUERY ) ); + m_meta.clear(); + m_settings.tables.clear(); + m_settings.users.clear(); + + for( WeakHashMap::iterator ii = m_myStatements.begin() ; + ii != m_myStatements.end() ; + ++ii ) + { + Reference< XCloseable > r = ii->second; + if( r.is() ) + lst.push_back( r ); + } + } + + // close all created statements + for( CloseableList::iterator ii = lst.begin(); ii != lst.end() ; ++ii ) + ii->get()->close(); + + // close all created statements + for( DisposeableList::iterator iiDispose = lstDispose.begin(); + iiDispose != lstDispose.end() ; ++iiDispose ) + { + if( iiDispose->is() ) + iiDispose->get()->dispose(); + } +} + + +void Connection::removeFromWeakMap( const ::rtl::ByteSequence & id ) +{ + // shrink the list ! + MutexGuard guard( m_refMutex->mutex ); + WeakHashMap::iterator ii = m_myStatements.find( id ); + if( ii != m_myStatements.end() ) + m_myStatements.erase( ii ); +} + +Reference< XStatement > Connection::createStatement( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + + Statement *stmt = new Statement( m_refMutex, this , &m_settings ); + Reference< XStatement > ret( stmt ); + ::rtl::ByteSequence id( 16 ); + rtl_createUuid( (sal_uInt8*) id.getConstArray(), 0 , sal_False ); + m_myStatements[ id ] = Reference< XCloseable > ( stmt ); + stmt->queryAdapter()->addReference( new ClosableReference( id, this ) ); + return ret; +} + +Reference< XPreparedStatement > Connection::prepareStatement( const ::rtl::OUString& sql ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + + rtl::OString byteSql = OUStringToOString( sql, m_settings.encoding ); + PreparedStatement *stmt = new PreparedStatement( m_refMutex, this, &m_settings, byteSql ); + Reference< XPreparedStatement > ret = stmt; + + ::rtl::ByteSequence id( 16 ); + rtl_createUuid( (sal_uInt8*) id.getConstArray(), 0 , sal_False ); + m_myStatements[ id ] = Reference< XCloseable > ( stmt ); + stmt->queryAdapter()->addReference( new ClosableReference( id, this ) ); + return ret; +} + +Reference< XPreparedStatement > Connection::prepareCall( const ::rtl::OUString& sql ) + throw (SQLException, RuntimeException) +{ + throw SQLException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( "pq_driver: Callable statements not supported" ) ), + Reference< XInterface > (), OUString() , 1, Any() ); +} + + +::rtl::OUString Connection::nativeSQL( const ::rtl::OUString& sql ) + throw (SQLException, RuntimeException) +{ + return sql; +} + +void Connection::setAutoCommit( sal_Bool autoCommit ) throw (SQLException, RuntimeException) +{ + // UNSUPPORTED +} + +sal_Bool Connection::getAutoCommit( ) throw (SQLException, RuntimeException) +{ + // UNSUPPORTED + return sal_True; +} + +void Connection::commit( ) throw (SQLException, RuntimeException) +{ + // UNSUPPORTED +} + +void Connection::rollback( ) throw (SQLException, RuntimeException) +{ + // UNSUPPORTED +} + +sal_Bool Connection::isClosed( ) throw (SQLException, RuntimeException) +{ + return m_settings.pConnection == 0; +} + +Reference< XDatabaseMetaData > Connection::getMetaData( ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + if( ! m_meta.is() ) + m_meta = new DatabaseMetaData( m_refMutex, this, &m_settings ); + return m_meta; +} + +void Connection::setReadOnly( sal_Bool readOnly ) throw (SQLException, RuntimeException) +{ + // UNSUPPORTED + +} + +sal_Bool Connection::isReadOnly( ) throw (SQLException, RuntimeException) +{ + // UNSUPPORTED + return sal_False; +} + +void Connection::setCatalog( const ::rtl::OUString& catalog ) + throw (SQLException, RuntimeException) +{ + // UNSUPPORTED +} + +::rtl::OUString Connection::getCatalog( ) throw (SQLException, RuntimeException) +{ + OUString ret; + MutexGuard ( m_refMutex->mutex ); + if( m_settings.pConnection == 0 ) + { + throw SQLException( ASCII_STR( "pq_connection: connection is closed" ), *this, + OUString(), 1, Any() ); + } + char * p = PQdb(m_settings.pConnection ); + return OUString( p, strlen(p) , m_settings.encoding ); +} + +void Connection::setTransactionIsolation( sal_Int32 level ) + throw (SQLException, RuntimeException) +{ + // UNSUPPORTED +} + +sal_Int32 Connection::getTransactionIsolation( ) throw (SQLException, RuntimeException) +{ + // UNSUPPORTED + return 0; +} + +Reference< XNameAccess > Connection::getTypeMap( ) throw (SQLException, RuntimeException) +{ + Reference< XNameAccess > t; + { + MutexGuard guard( m_refMutex->mutex ); + t = m_typeMap; + } + return t; +} + +void Connection::setTypeMap( const Reference< XNameAccess >& typeMap ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + m_typeMap = typeMap; +} +Any Connection::getWarnings( ) throw (SQLException, RuntimeException) +{ + return Any(); +} + +void Connection::clearWarnings( ) throw (SQLException, RuntimeException) +{ +} + + +static OString properties2String( const OString initialString, + const Sequence< PropertyValue > & args, + const Reference< XTypeConverter> &tc ) +{ + OStringBuffer ret; + + ret.append( initialString ); + if( initialString.getLength() ) + ret.append( " " ); + + bool initial = false; + for( int i = 0; i < args.getLength() ; i ++) + { + bool append = true; + if( args[i].Name.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "password" ) ) ) + { + ret.append( "password=" ); + } + else if( args[i].Name.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "user" ) ) ) + { + ret.append( "user=" ); + } + else if( args[i].Name.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "port" ) ) ) + { + ret.append( "port=" ); + } + else if( args[i].Name.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "dbname" ) ) ) + { + ret.append( "dbname=" ); + } + else if( args[i].Name.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "connect_timeout" ) ) ) + { + ret.append( "connect_timeout=" ); + } + else if( args[i].Name.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "options" ) ) ) + { + ret.append( "options=" ); + } + else if( args[i].Name.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "requiressl" ) ) ) + { + ret.append( "requiressl=" ); + } + else + { + append = false; + // ignore for now + } + if( append ) + { + OUString value; + tc->convertTo( args[i].Value ,getCppuType( &value) ) >>= value; + ret.append( OUStringToOString( value, RTL_TEXTENCODING_UTF8) ); + ret.append( " " ); + } + } + + return ret.makeStringAndClear(); +} + +void Connection::initialize( const Sequence< Any >& aArguments ) + throw (Exception, RuntimeException) +{ + OUString url; + Sequence< PropertyValue > args; + + Reference< XTypeConverter > tc( m_ctx->getServiceManager()->createInstanceWithContext( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" ) ), m_ctx ), + UNO_QUERY); + if( ! tc.is() ) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("pq_driver: Couldn't instantiate converter service" )), + Reference< XInterface > () ); + } + if( aArguments.getLength() != 2 ) + { + OUStringBuffer buf(128); + buf.appendAscii( "pq_driver: expected 2 arguments, got " ); + buf.append( aArguments.getLength( ) ); + throw IllegalArgumentException(buf.makeStringAndClear(), Reference< XInterface > () , 0 ); + } + + if( ! (aArguments[0] >>= url) ) + { + OUStringBuffer buf(128); + buf.appendAscii( "pq_driver: expected string as first argument, got " ); + buf.append( aArguments[0].getValueType().getTypeName() ); + throw IllegalArgumentException( buf.makeStringAndClear() , *this, 0 ); + } + + tc->convertTo( aArguments[1], getCppuType( &args ) ) >>= args; + + OString o; + int nColon = url.indexOf( ':' ); + if( nColon != -1 ) + { + nColon = url.indexOf( ':' , 1+ nColon ); + if( nColon != -1 ) + { + o = OUStringToOString( url.getStr()+nColon+1, m_settings.encoding ); + } + } + o = properties2String( o , args , tc ); + + m_settings.pConnection = PQconnectdb( o.getStr() ); + if( ! m_settings.pConnection ) + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( "pq_driver: out of memory" ) ), + Reference< XInterface > () ); + if( PQstatus( m_settings.pConnection ) == CONNECTION_BAD ) + { + OUStringBuffer buf( 128 ); + + const char * error = PQerrorMessage( m_settings.pConnection ); + OUString errorMessage( error, strlen( error) , RTL_TEXTENCODING_ASCII_US ); + buf.appendAscii( "Couldn't establish database connection to '" ); + buf.append( url ); + buf.appendAscii( "' (" ); + buf.append( errorMessage ); + buf.appendAscii( ")" ); + PQfinish( m_settings.pConnection ); + m_settings.pConnection = 0; + throw SQLException( buf.makeStringAndClear(), *this, errorMessage, CONNECTION_BAD, Any() ); + } + PQsetClientEncoding( m_settings.pConnection, "UNICODE" ); + char *p = PQuser( m_settings.pConnection ); + m_settings.user = OUString( p, strlen(p), RTL_TEXTENCODING_UTF8); + p = PQdb( m_settings.pConnection ); + m_settings.catalog = OUString( p, strlen(p), RTL_TEXTENCODING_UTF8); + m_settings.tc = tc; + + if( isLog( &m_settings, LogLevel::INFO ) ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "connection to '" ); + buf.append( url ); + buf.appendAscii( "' successfully opened" ); + log( &m_settings, LogLevel::INFO, buf.makeStringAndClear() ); + } +} + +void Connection::disposing() +{ + close(); +} + +void Connection::checkClosed() throw ( SQLException, RuntimeException ) +{ + if( !m_settings.pConnection ) + throw SQLException( ASCII_STR( "pq_connection: Connection already closed" ), + *this, OUString(), 1, Any() ); +} + +Reference< XNameAccess > Connection::getTables( ) + throw (::com::sun::star::uno::RuntimeException) +{ + if( isLog( &m_settings, LogLevel::INFO ) ) + { + log( &m_settings, LogLevel::INFO, "Connection::getTables() got called" ); + } + MutexGuard guard( m_refMutex->mutex ); + if( !m_settings.tables.is() ) + m_settings.tables = Tables::create( m_refMutex, this, &m_settings , &m_settings.pTablesImpl); + else + // TODO: how to overcome the performance problem ? + Reference< com::sun::star::util::XRefreshable > ( m_settings.tables, UNO_QUERY )->refresh(); + return m_settings.tables; +} + +Reference< XNameAccess > Connection::getViews( ) + throw (::com::sun::star::uno::RuntimeException) +{ + if( isLog( &m_settings, LogLevel::INFO ) ) + { + log( &m_settings, LogLevel::INFO, "Connection::getViews() got called" ); + } + MutexGuard guard( m_refMutex->mutex ); + if( !m_settings.views.is() ) + m_settings.views = Views::create( m_refMutex, this, &m_settings, &(m_settings.pViewsImpl) ); + else + // TODO: how to overcome the performance problem ? + Reference< com::sun::star::util::XRefreshable > ( m_settings.views, UNO_QUERY )->refresh(); + return m_settings.views; +} + + + +Reference< XNameAccess > Connection::getUsers( ) + throw (::com::sun::star::uno::RuntimeException) +{ + if( isLog( &m_settings, LogLevel::INFO ) ) + { + log( &m_settings, LogLevel::INFO, "Connection::getUsers() got called" ); + } + + MutexGuard guard( m_refMutex->mutex ); + if( !m_settings.users.is() ) + m_settings.users = Users::create( m_refMutex, this, &m_settings ); + return m_settings.users; +} + + +Reference< XInterface > ConnectionCreateInstance( + const Reference< XComponentContext > & ctx ) throw (Exception) +{ + ::rtl::Reference< RefCountedMutex > ref = new RefCountedMutex(); + return * new Connection( ref, ctx ); +} + + + +bool isLog( ConnectionSettings *settings, int loglevel ) +{ + return settings->loglevel >= loglevel && settings->logFile; +} + +void log( ConnectionSettings *settings, sal_Int32 level, const OUString &logString ) +{ + log( settings, level, OUStringToOString( logString, settings->encoding ).getStr() ); +} +void log( ConnectionSettings *settings, sal_Int32 level, const char *str ) +{ + if( isLog( settings, level ) ) + { + static const char *strLevel[] = { "NONE", "ERROR", "SQL", "INFO", "DATA" }; + + time_t t = ::time( 0 ); + char *pString; +#ifdef SAL_W32 + pString = asctime( localtime( &t ) ); +#else + struct tm timestruc; + char timestr[50]; + memset( timestr, 0 , 50); + pString = timestr; + ::localtime_r( &t , ×truc ); + asctime_r( ×truc, timestr ); +#endif + for( int i = 0 ; pString[i] ; i ++ ) + { + if( pString[i] <= 13 ) + { + pString[i] = 0; + break; + } + } + fprintf( settings->logFile, "%s [%s]: %s\n", pString, strLevel[level], str ); + } +} + + +} + + + +static struct cppu::ImplementationEntry g_entries[] = +{ + { + pq_sdbc_driver::ConnectionCreateInstance, pq_sdbc_driver::ConnectionGetImplementationName, + pq_sdbc_driver::ConnectionGetSupportedServiceNames, cppu::createSingleComponentFactory, + 0 , 0 + }, + { 0, 0, 0, 0, 0, 0 } +}; + + +extern "C" +{ + +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + return cppu::component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries ); +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + return cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries ); +} + +} diff --git connectivity/source/drivers/postgresql/pq_connection.hxx connectivity/source/drivers/postgresql/pq_connection.hxx new file mode 100644 index 0000000..322e375 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_connection.hxx @@ -0,0 +1,285 @@ +/************************************************************************* + * + * $RCSfile: pq_connection.hxx,v $ + * + * $Revision: 1.1.2.4 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:26:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_CONNECTION_HXX_ +#define _PQ_CONNECTION_HXX_ +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include + +#include +#include "pq_allocator.hxx" + +namespace pq_sdbc_driver +{ +#ifdef POSTGRE_TRACE +#define POSTGRE_TRACE( x ) printf( "%s\n" , x ) +#define POSTGRE_TRACE_1( x ,y) printf( "%s %s\n" , x ,y ) +#else +#define POSTGRE_TRACE(x) ((void)0) +#define POSTGRE_TRACE_1(x,y) ((void)0) +#endif + +class RefCountedMutex : public salhelper::SimpleReferenceObject +{ +public: + osl::Mutex mutex; +}; + +struct ConnectionSettings; + + + +//-------------------------------------------------- +// Logging API +//-------------------------------------------------- +namespace LogLevel +{ +// when you add a loglevel, extend the log function ! +static const sal_Int32 NONE = 0; +static const sal_Int32 ERROR = 1; +static const sal_Int32 SQL = 2; +static const sal_Int32 INFO = 3; +static const sal_Int32 DATA = 4; +} +bool isLog( ConnectionSettings *settings, int loglevel ); +void log( ConnectionSettings *settings, sal_Int32 level, const rtl::OUString &logString ); +void log( ConnectionSettings *settings, sal_Int32 level, const char *str ); +//-------------------------------------------------- + +class Tables; +class Views; +struct ConnectionSettings +{ + ConnectionSettings() : + showSystemColumns( sal_False ), + pConnection(0), + encoding( RTL_TEXTENCODING_UTF8), + logFile( 0 ), + loglevel( LogLevel::INFO ) + {} + rtl_TextEncoding encoding; + PGconn *pConnection; + ::com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter > tc; + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > tables; + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > users; + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > views; + Tables *pTablesImpl; // needed to implement renaming of tables / views + Views *pViewsImpl; // needed to implement renaming of tables / views + ::rtl::OUString user; + ::rtl::OUString catalog; + sal_Bool showSystemColumns; + FILE *logFile; + sal_Int32 loglevel; +}; + +//-------------------------------------------------- +typedef cppu::WeakComponentImplHelper6< + com::sun::star::sdbc::XConnection, + com::sun::star::sdbc::XWarningsSupplier, + com::sun::star::lang::XInitialization, + com::sun::star::sdbcx::XTablesSupplier, + com::sun::star::sdbcx::XViewsSupplier, + com::sun::star::sdbcx::XUsersSupplier > ConnectionBase; + +// some types +struct HashByteSequence +{ + sal_Int32 operator () ( const ::rtl::ByteSequence & seq ) const + { + return *(sal_Int32*) seq.getConstArray(); + } +}; + +typedef ::std::hash_map< + ::rtl::ByteSequence, + ::com::sun::star::uno::WeakReference< com::sun::star::sdbc::XCloseable >, + HashByteSequence, + ::std::equal_to< ::rtl::ByteSequence >, + Allocator< std::pair< const ::rtl::ByteSequence,::com::sun::star::uno::WeakReference< com::sun::star::sdbc::XCloseable > > > +> WeakHashMap; +typedef ::std::vector< rtl::OString, Allocator< ::rtl::OString > > OStringVector; + + + +typedef std::hash_map +< + const sal_Int32, + rtl::OUString, + ::std::hash< sal_Int32 >, + ::std::equal_to< sal_Int32 >, + Allocator< ::std::pair< sal_Int32, ::rtl::OUString > > +> Int2StringMap; + +class Connection : public ConnectionBase +{ + ::com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_ctx; + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_typeMap; + ConnectionSettings m_settings; + ::rtl::Reference< RefCountedMutex > m_refMutex; + ::com::sun::star::uno::Reference< com::sun::star::sdbc::XDatabaseMetaData > m_meta; + WeakHashMap m_myStatements; + +private: + void checkClosed() + throw ( com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException ); + +public: + Connection( + const rtl::Reference< RefCountedMutex > &refMutex, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & ctx ); + + ~Connection( ); + +public: // XCloseable + virtual void SAL_CALL close() + throw ( ::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException ); + +public: // XConnection + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XStatement > SAL_CALL createStatement( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareStatement( + const ::rtl::OUString& sql ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareCall( + const ::rtl::OUString& sql ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL nativeSQL( const ::rtl::OUString& sql ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setAutoCommit( sal_Bool autoCommit ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL getAutoCommit( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL commit( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL rollback( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isClosed( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< com::sun::star::sdbc::XDatabaseMetaData > SAL_CALL getMetaData( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setReadOnly( sal_Bool readOnly ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isReadOnly( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setCatalog( const ::rtl::OUString& catalog ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getCatalog( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setTransactionIsolation( sal_Int32 level ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getTransactionIsolation( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > SAL_CALL getTypeMap( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setTypeMap( + const ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& typeMap ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XWarningsSupplier + virtual ::com::sun::star::uno::Any SAL_CALL getWarnings( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearWarnings( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw (com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + +public: // XTablesSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTables( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XUsersSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getUsers( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XViewsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getViews( ) throw (::com::sun::star::uno::RuntimeException); + +public: + virtual void SAL_CALL disposing(); + +public: // helper function + void removeFromWeakMap( const ::rtl::ByteSequence & seq ); +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_databasemetadata.cxx connectivity/source/drivers/postgresql/pq_databasemetadata.cxx new file mode 100644 index 0000000..b3c18d8 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_databasemetadata.cxx @@ -0,0 +1,2164 @@ +/************************************************************************* + * + * $RCSfile: pq_databasemetadata.cxx,v $ + * + * $Revision: 1.1.2.11 $ + * + * last change: $Author: jbu $ $Date: 2007/02/15 20:04:47 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#include +#include "pq_databasemetadata.hxx" +#include "pq_driver.hxx" +#include "pq_sequenceresultset.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using ::osl::MutexGuard; + +using ::rtl::OUString; + +using com::sun::star::sdbc::SQLException; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +// using com::sun::star::sdbc::IndexType; +// using com::sun::star::sdbc::DataType; + +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Sequence; + +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; + +namespace pq_sdbc_driver +{ +typedef +std::vector +< + com::sun::star::uno::Sequence< com::sun::star::uno::Any >, + Allocator< com::sun::star::uno::Sequence< com::sun::star::uno::Any > > +> SequenceAnyVector; + + +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +static const int MAX_COLUMNS_IN_GROUPBY = 16; +static const int MAX_COLUMNS_IN_INDEX = 32; +static const int MAX_COLUMNS_IN_ORDER_BY = 16; +static const int MAX_COLUMNS_IN_SELECT = 1024; +static const int MAX_IDENTIFIER_LENGTH = 63; +static const int MAX_COLUMNS_IN_TABLE = 1024; +static const int MAX_CONNECTIONS = 0xffff; +static const int MAX_STATEMENTS = 0xffff; +static const int MAX_STATEMENT_LENGTH = -1; +static const int MAX_TABLES_IN_SELECT = 0xffff; +static const int MAX_USER_NAME_LENGTH = MAX_IDENTIFIER_LENGTH; + + +// alphabetically ordered ! +static const int PRIVILEGE_CREATE = 0x1; +static const int PRIVILEGE_DELETE = 0x2; +static const int PRIVILEGE_EXECUTE = 0x4; +static const int PRIVILEGE_INSERT = 0x8; +static const int PRIVILEGE_REFERENCES = 0x10; +static const int PRIVILEGE_RULE = 0x20; +static const int PRIVILEGE_SELECT = 0x40; +static const int PRIVILEGE_TEMPORARY = 0x80; +static const int PRIVILEGE_TRIGGER = 0x100; +static const int PRIVILEGE_UPDATE = 0x200; +static const int PRIVILEGE_USAGE = 0x400; +static const int PRIVILEGE_MAX = PRIVILEGE_USAGE; + +void DatabaseMetaData::checkClosed() + throw (SQLException, RuntimeException) +{ +} + +DatabaseMetaData::DatabaseMetaData( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ) + : m_pSettings( pSettings ), + m_origin( origin ), + m_refMutex( refMutex ) + +{ + +} + +sal_Bool DatabaseMetaData::allProceduresAreCallable( ) throw (SQLException, RuntimeException) +{ + // TODO + return sal_False; +} + +sal_Bool DatabaseMetaData::allTablesAreSelectable( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +OUString DatabaseMetaData::getURL( ) throw (SQLException, RuntimeException) +{ + // TODO + return OUString(); +} + +OUString DatabaseMetaData::getUserName( ) throw (SQLException, RuntimeException) +{ + return m_pSettings->user; +} + +sal_Bool DatabaseMetaData::isReadOnly( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + + +sal_Bool DatabaseMetaData::nullsAreSortedHigh( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::nullsAreSortedLow( ) throw (SQLException, RuntimeException) +{ + return ! nullsAreSortedHigh(); +} + +sal_Bool DatabaseMetaData::nullsAreSortedAtStart( ) throw (SQLException, RuntimeException) +{ + return ! nullsAreSortedHigh(); +} + +sal_Bool DatabaseMetaData::nullsAreSortedAtEnd( ) throw (SQLException, RuntimeException) +{ + return nullsAreSortedHigh(); +} + +OUString DatabaseMetaData::getDatabaseProductName( ) throw (SQLException, RuntimeException) +{ + return ASCII_STR( "postgresql"); +} + +OUString DatabaseMetaData::getDatabaseProductVersion( ) throw (SQLException, RuntimeException) +{ + return ASCII_STR( POSTGRESQL_VERSION ); +} +OUString DatabaseMetaData::getDriverName( ) throw (SQLException, RuntimeException) +{ + return ASCII_STR( "postgresql-sdbc" ); +} + +OUString DatabaseMetaData::getDriverVersion( ) throw (SQLException, RuntimeException) +{ + return ASCII_STR( PQ_SDBC_DRIVER_VERSION ); +} + +sal_Int32 DatabaseMetaData::getDriverMajorVersion( ) throw (RuntimeException) +{ + return PQ_SDBC_MAJOR; +} + +sal_Int32 DatabaseMetaData::getDriverMinorVersion( ) throw (RuntimeException) +{ + return PQ_SDBC_MINOR; +} + +sal_Bool DatabaseMetaData::usesLocalFiles( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::usesLocalFilePerTable( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsMixedCaseIdentifiers( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::storesUpperCaseIdentifiers( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::storesLowerCaseIdentifiers( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + + +sal_Bool DatabaseMetaData::storesMixedCaseIdentifiers( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + + +sal_Bool DatabaseMetaData::supportsMixedCaseQuotedIdentifiers( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::storesUpperCaseQuotedIdentifiers( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + + +sal_Bool DatabaseMetaData::storesLowerCaseQuotedIdentifiers( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + + +sal_Bool DatabaseMetaData::storesMixedCaseQuotedIdentifiers( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + + +OUString DatabaseMetaData::getIdentifierQuoteString( ) throw (SQLException, RuntimeException) +{ + return ASCII_STR( "\"" ); +} + +OUString DatabaseMetaData::getSQLKeywords( ) throw (SQLException, RuntimeException) +{ + return ASCII_STR( + "ANALYZE," + "ANALYSE," + "DO," + "ILIKE," + "LIMIT," + "NEW," + "OFFSET," + "OLD," + "PLACING" ); +} +OUString DatabaseMetaData::getNumericFunctions( ) throw (SQLException, RuntimeException) +{ + // TODO + return OUString(); +} + +OUString DatabaseMetaData::getStringFunctions( ) throw (SQLException, RuntimeException) +{ + // TODO + return OUString(); +} + +OUString DatabaseMetaData::getSystemFunctions( ) throw (SQLException, RuntimeException) +{ + // TODO + return OUString(); +} +OUString DatabaseMetaData::getTimeDateFunctions( ) throw (SQLException, RuntimeException) +{ + // TODO + return OUString(); +} +OUString DatabaseMetaData::getSearchStringEscape( ) throw (SQLException, RuntimeException) +{ + return ASCII_STR( "\\" ); +} +OUString DatabaseMetaData::getExtraNameCharacters( ) throw (SQLException, RuntimeException) +{ + // TODO + return OUString(); +} + +sal_Bool DatabaseMetaData::supportsAlterTableWithAddColumn( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsAlterTableWithDropColumn( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsColumnAliasing( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::nullPlusNonNullIsNull( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsTypeConversion( ) throw (SQLException, RuntimeException) // TODO, DON'T KNOW +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsConvert( sal_Int32 fromType, sal_Int32 toType ) throw (SQLException, RuntimeException) // TODO +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsTableCorrelationNames( ) throw (SQLException, RuntimeException) // TODO, don't know +{ + return sal_True; +} + + +sal_Bool DatabaseMetaData::supportsDifferentTableCorrelationNames( ) throw (SQLException, RuntimeException) // TODO, don't know +{ + + return sal_True; +} +sal_Bool DatabaseMetaData::supportsExpressionsInOrderBy( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsOrderByUnrelated( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsGroupBy( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsGroupByUnrelated( ) throw (SQLException, RuntimeException) // TODO, DONT know +{ + + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsGroupByBeyondSelect( ) throw (SQLException, RuntimeException) // TODO, DON'T know +{ + + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsLikeEscapeClause( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsMultipleResultSets( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsMultipleTransactions( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsNonNullableColumns( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + + +sal_Bool DatabaseMetaData::supportsMinimumSQLGrammar( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsCoreSQLGrammar( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsExtendedSQLGrammar( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsANSI92EntryLevelSQL( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsANSI92IntermediateSQL( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsANSI92FullSQL( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsIntegrityEnhancementFacility( ) throw (SQLException, RuntimeException) +{ + // TODO + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsOuterJoins( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsFullOuterJoins( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsLimitedOuterJoins( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + + +OUString DatabaseMetaData::getSchemaTerm( ) throw (SQLException, RuntimeException) +{ + return ASCII_STR( "SCHEMA" ); +} + +OUString DatabaseMetaData::getProcedureTerm( ) throw (SQLException, RuntimeException) +{ + // don't know + return OUString(); +} + +OUString DatabaseMetaData::getCatalogTerm( ) throw (SQLException, RuntimeException) +{ + // TODO is this correct ? + return ASCII_STR( "DATABASE" ); +} + +sal_Bool DatabaseMetaData::isCatalogAtStart( ) throw (SQLException, RuntimeException) // TODO don't know +{ + + return sal_True; +} + +OUString DatabaseMetaData::getCatalogSeparator( ) throw (SQLException, RuntimeException) +{ + // TODO don't know + return ASCII_STR( "." ); +} + +sal_Bool DatabaseMetaData::supportsSchemasInDataManipulation( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsSchemasInProcedureCalls( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsSchemasInTableDefinitions( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsSchemasInIndexDefinitions( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsSchemasInPrivilegeDefinitions( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsCatalogsInDataManipulation( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsCatalogsInProcedureCalls( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsCatalogsInTableDefinitions( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + + +sal_Bool DatabaseMetaData::supportsCatalogsInIndexDefinitions( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + + +sal_Bool DatabaseMetaData::supportsCatalogsInPrivilegeDefinitions( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + + +sal_Bool DatabaseMetaData::supportsPositionedDelete( ) throw (SQLException, RuntimeException) +{ + // TODO + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsPositionedUpdate( ) throw (SQLException, RuntimeException) +{ + // TODO + return sal_True; +} + + +sal_Bool DatabaseMetaData::supportsSelectForUpdate( ) throw (SQLException, RuntimeException) +{ + // TODO + return sal_False; +} + + +sal_Bool DatabaseMetaData::supportsStoredProcedures( ) throw (SQLException, RuntimeException) +{ + // TODO + return sal_False; +} + + +sal_Bool DatabaseMetaData::supportsSubqueriesInComparisons( ) throw (SQLException, RuntimeException) +{ + // TODO , don't know + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsSubqueriesInExists( ) throw (SQLException, RuntimeException) +{ + // TODO , don't know + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsSubqueriesInIns( ) throw (SQLException, RuntimeException) +{ + // TODO , don't know + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsSubqueriesInQuantifieds( ) throw (SQLException, RuntimeException) +{ + // TODO , don't know + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsCorrelatedSubqueries( ) throw (SQLException, RuntimeException) +{ + // TODO , don't know + return sal_True; +} +sal_Bool DatabaseMetaData::supportsUnion( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsUnionAll( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsOpenCursorsAcrossCommit( ) throw (SQLException, RuntimeException) +{ + // TODO, don't know + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsOpenCursorsAcrossRollback( ) throw (SQLException, RuntimeException) +{ + // TODO, don't know + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsOpenStatementsAcrossCommit( ) throw (SQLException, RuntimeException) +{ + // TODO, don't know + return sal_False; +} +sal_Bool DatabaseMetaData::supportsOpenStatementsAcrossRollback( ) throw (SQLException, RuntimeException) +{ + // TODO, don't know + return sal_False; +} + +sal_Int32 DatabaseMetaData::getMaxBinaryLiteralLength( ) throw (SQLException, RuntimeException) +{ + // TODO, don't know + return -1; +} + +sal_Int32 DatabaseMetaData::getMaxCharLiteralLength( ) throw (SQLException, RuntimeException) +{ + return -1; +} + +sal_Int32 DatabaseMetaData::getMaxColumnNameLength( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_IDENTIFIER_LENGTH; +} + +sal_Int32 DatabaseMetaData::getMaxColumnsInGroupBy( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_COLUMNS_IN_GROUPBY; +} + +sal_Int32 DatabaseMetaData::getMaxColumnsInIndex( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_COLUMNS_IN_INDEX; +} + +sal_Int32 DatabaseMetaData::getMaxColumnsInOrderBy( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_COLUMNS_IN_ORDER_BY; +} + +sal_Int32 DatabaseMetaData::getMaxColumnsInSelect( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_COLUMNS_IN_SELECT; +} + +sal_Int32 DatabaseMetaData::getMaxColumnsInTable( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_COLUMNS_IN_TABLE; +} + +sal_Int32 DatabaseMetaData::getMaxConnections( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_CONNECTIONS; +} + +sal_Int32 DatabaseMetaData::getMaxCursorNameLength( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_IDENTIFIER_LENGTH; +} + +sal_Int32 DatabaseMetaData::getMaxIndexLength( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_IDENTIFIER_LENGTH; +} + +sal_Int32 DatabaseMetaData::getMaxSchemaNameLength( ) throw (SQLException, RuntimeException) +{ + return MAX_IDENTIFIER_LENGTH; +} + +sal_Int32 DatabaseMetaData::getMaxProcedureNameLength( ) throw (SQLException, RuntimeException) +{ + return MAX_IDENTIFIER_LENGTH; +} + +sal_Int32 DatabaseMetaData::getMaxCatalogNameLength( ) throw (SQLException, RuntimeException) +{ + return MAX_IDENTIFIER_LENGTH; +} + +sal_Int32 DatabaseMetaData::getMaxRowSize( ) throw (SQLException, RuntimeException) +{ + return -1; +} + +sal_Bool DatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Int32 DatabaseMetaData::getMaxStatementLength( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_STATEMENT_LENGTH; +} + +sal_Int32 DatabaseMetaData::getMaxStatements( ) throw (SQLException, RuntimeException) //TODO, don't know +{ + return MAX_STATEMENTS; +} + +sal_Int32 DatabaseMetaData::getMaxTableNameLength( ) throw (SQLException, RuntimeException) +{ + return MAX_IDENTIFIER_LENGTH; +} + +sal_Int32 DatabaseMetaData::getMaxTablesInSelect( ) throw (SQLException, RuntimeException) +{ + return MAX_TABLES_IN_SELECT; +} + +sal_Int32 DatabaseMetaData::getMaxUserNameLength( ) throw (SQLException, RuntimeException) +{ + return MAX_USER_NAME_LENGTH; +} + +sal_Int32 DatabaseMetaData::getDefaultTransactionIsolation( ) throw (SQLException, RuntimeException) +{ + return com::sun::star::sdbc::TransactionIsolation::READ_COMMITTED; +} + +sal_Bool DatabaseMetaData::supportsTransactions( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsTransactionIsolationLevel( sal_Int32 level ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions( ) + throw (SQLException, RuntimeException) +{ + return sal_True; +} + +sal_Bool DatabaseMetaData::supportsDataManipulationTransactionsOnly( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::dataDefinitionCausesTransactionCommit( ) throw (SQLException, RuntimeException) +{ + // don't know + return sal_True; +} + +sal_Bool DatabaseMetaData::dataDefinitionIgnoredInTransactions( ) throw (SQLException, RuntimeException) +{ + return sal_True; +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getProcedures( + const ::com::sun::star::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& procedureNamePattern ) throw (SQLException, RuntimeException) +{ +// 1. PROCEDURE_CAT string => procedure catalog (may be NULL ) +// 2. PROCEDURE_SCHEM string => procedure schema (may be NULL ) +// 3. PROCEDURE_NAME string => procedure name +// 4. reserved for future use +// 5. reserved for future use +// 6. reserved for future use +// 7. REMARKS string => explanatory comment on the procedure +// 8. PROCEDURE_TYPE short => kind of procedure: +// * UNKNOWN - May return a result +// * NO - Does not return a result +// * RETURN - Returns a result + + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new SequenceResultSet( + m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getProcedureColumns( + const ::com::sun::star::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& procedureNamePattern, + const OUString& columnNamePattern ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new SequenceResultSet( + m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getTables( + const ::com::sun::star::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& tableNamePattern, + const ::com::sun::star::uno::Sequence< OUString >& types ) + throw (SQLException, RuntimeException) +{ + Statics &statics = getStatics(); + + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + rtl::OUStringBuffer buf( 128 ); + buf.appendAscii( "DatabaseMetaData::getTables got called with " ); + buf.append( schemaPattern ); + buf.appendAscii( "." ); + buf.append( tableNamePattern ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() ); + } + // ignore catalog, as a single pq connection does not support multiple catalogs + + Reference< XPreparedStatement > statement = m_origin->prepareStatement( + ASCII_STR( + "SELECT " + "DISTINCT ON (pg_namespace.nspname, relname ) " // avoid duplicates (pg_settings !) + "pg_namespace.nspname, relname, relkind, pg_description.description " + "FROM pg_namespace, pg_class LEFT JOIN pg_description ON pg_class.oid = pg_description.objoid " + "WHERE relnamespace = pg_namespace.oid " + "AND ( relkind = 'r' OR relkind = 'v') " + "AND pg_namespace.nspname LIKE ? " + "AND relname LIKE ? " +// "ORDER BY pg_namespace.nspname || relname" + ) ); + + Reference< XParameters > parameters( statement, UNO_QUERY ); + parameters->setString( 1 , schemaPattern ); + parameters->setString( 2 , tableNamePattern ); + + Reference< XResultSet > rs = statement->executeQuery(); + Reference< XRow > xRow( rs, UNO_QUERY ); + SequenceAnyVector vec; + + while( rs->next() ) + { + Sequence< Any > row( 5 ); + + row[0] <<= m_pSettings->catalog; + row[1] <<= xRow->getString( 1 ); + row[2] <<= xRow->getString( 2 ); + OUString type = xRow->getString(3); + if( 0 == type.compareToAscii( "r" ) ) + { + if( 0 == xRow->getString(1).compareToAscii( "pg_catalog" ) ) + { + row[3] <<= statics.SYSTEM_TABLE; + } + else + { + row[3] <<= statics.TABLE; + } + } + else if( 0 == type.compareToAscii( "v" ) ) + { + row[3] <<= statics.VIEW; + } + else + { + row[3] <<= statics.UNKNOWN; + } + row[4] <<= xRow->getString(4); + + // no description in postgresql AFAIK + vec.push_back( row ); + } + Reference< XCloseable > closeable( statement, UNO_QUERY ); + if( closeable.is() ) + closeable->close(); + + return new SequenceResultSet( + m_refMutex, *this, statics.tablesRowNames, + Sequence< Sequence< Any > > ( &vec[0],vec.size() ), m_pSettings->tc ); +} + +struct SortInternalSchemasLastAndPublicFirst +{ + bool operator () ( const Sequence< Any > & a, const Sequence< Any > & b ) + { + OUString valueA; + OUString valueB; + a[0] >>= valueA; + b[0] >>= valueB; + bool ret = false; + if( valueA.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "public" ) ) == 0 ) + { + ret = true; + } + else if( valueB.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "public" ) ) == 0 ) + { + ret = false; + } + else if( valueA.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ) && + valueB.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ) ) + { + ret = valueA.compareTo( valueB ) < 0; // sorts equal ! + } + else if( valueA.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) )) + { + ret = false; // sorts last ! + } + else if( valueB.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ) ) + { + ret = true; // sorts dorst ! + + } + else + { + ret = (valueA.compareTo( valueB ) < 0); + } + return ret; + } +}; + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getSchemas( ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + log( m_pSettings, LogLevel::INFO, "DatabaseMetaData::getSchemas() got called" ); + } + // TABLE_SCHEM string =&gt; schema name + Reference< XStatement > statement = m_origin->createStatement(); + Reference< XResultSet > rs = statement->executeQuery( + ASCII_STR("SELECT nspname from pg_namespace") ); + + Reference< XRow > xRow( rs, UNO_QUERY ); + SequenceAnyVector vec; + while( rs->next() ) + { + Sequence row(1); + row[0] <<= xRow->getString(1); + vec.push_back( row ); + } + + // sort public first, sort internal schemas last, sort rest in alphabetic order + std::sort( vec.begin(), vec.end(), SortInternalSchemasLastAndPublicFirst() ); + + Reference< XCloseable > closeable( statement, UNO_QUERY ); + if( closeable.is() ) + closeable->close(); + return new SequenceResultSet( + m_refMutex, *this, getStatics().schemaNames, + Sequence< Sequence< Any > > ( &vec[0], vec.size() ), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getCatalogs( ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new SequenceResultSet( + m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getTableTypes( ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new SequenceResultSet( + m_refMutex, *this, getStatics().tableTypeNames, getStatics().tableTypeData, + m_pSettings->tc ); +} + + +/** returns the constant from sdbc.DataType + */ +sal_Int32 typeNameToDataType( const OUString &typeName, const OUString &typtype ) +{ +// sal_Int32 ret = com::sun::star::sdbc::DataType::DISTINCT; + // map all unknown types to memo (longvarchar). This allows to show them in + // string representation. Additionally, the edit-table-type-selection-box + // is not so unuseable anymore. + sal_Int32 ret = com::sun::star::sdbc::DataType::LONGVARCHAR; + if( 0 == typtype.compareToAscii( "b" ) ) + { + // as long as the OOo framework does not support arrays, + // the user is better of with interpreting arrays as strings ! +// if( typeName.getLength() && '_' == typeName[0] ) +// { +// its just a naming convention, but as long as we don't have anything better, +// we take it as granted +// ret = com::sun::star::sdbc::DataType::ARRAY; +// } + // base type + Statics &statics = getStatics(); + BaseTypeMap::iterator ii = statics.baseTypeMap.find( typeName ); + if( ii != statics.baseTypeMap.end() ) + { + ret = ii->second; + } + } + else if( 0 == typtype.compareToAscii( "c" ) ) + { + ret = com::sun::star::sdbc::DataType::STRUCT; + } + else if( 0 == typtype.compareToAscii( "d" ) ) + { + ret = com::sun::star::sdbc::DataType::LONGVARCHAR; + } + return ret; +} + +static bool isSystemColumn( const OUString &columnName ) +{ + return + columnName.compareToAscii( "oid" ) == 0 || + columnName.compareToAscii( "tableoid" ) == 0 || + columnName.compareToAscii( "xmin" ) == 0 || + columnName.compareToAscii( "cmin" ) == 0 || + columnName.compareToAscii( "xmax" ) == 0 || + columnName.compareToAscii( "cmax" ) == 0 || + columnName.compareToAscii( "ctid" ) == 0; +} + +// is not exported by the postgres header +const static int PQ_VARHDRSZ = sizeof( sal_Int32 ); + +static void extractPrecisionAndScale( + sal_Int32 dataType, sal_Int32 atttypmod, sal_Int32 *precision, sal_Int32 *scale ) +{ + if( atttypmod < PQ_VARHDRSZ ) + { + *precision = 0; + *scale = 0; + } + else + { + switch( dataType ) + { + case com::sun::star::sdbc::DataType::NUMERIC: + case com::sun::star::sdbc::DataType::DECIMAL: + { + *precision = ( ( atttypmod - PQ_VARHDRSZ ) >> 16 ) & 0xffff; + *scale = (atttypmod - PQ_VARHDRSZ ) & 0xffff; + break; + } + default: + *precision = atttypmod - PQ_VARHDRSZ; + *scale = 0; + } + } +} + +struct DatabaseTypeDescription +{ + DatabaseTypeDescription() + {} + DatabaseTypeDescription( const OUString &name, const OUString & type ) : + typeName( name ), + typeType( type ) + {} + DatabaseTypeDescription( const DatabaseTypeDescription &source ) : + typeName( source.typeName ), + typeType( source.typeType ) + {} + DatabaseTypeDescription & operator = ( const DatabaseTypeDescription & source ) + { + typeName = source.typeName; + typeType = source.typeType; + return *this; + } + OUString typeName; + OUString typeType; +}; + +typedef std::hash_map +< + sal_Int32, + DatabaseTypeDescription, + ::std::hash< sal_Int32 >, + ::std::equal_to< sal_Int32 >, + Allocator< ::std::pair< sal_Int32, DatabaseTypeDescription > > +> Oid2DatabaseTypeDescriptionMap; + +static void columnMetaData2DatabaseTypeDescription( + Oid2DatabaseTypeDescriptionMap &oidMap, + const Reference< XResultSet > &rs, + const Reference< XStatement > &stmt ) +{ + Reference< XRow > row( rs, UNO_QUERY ); + int domains = 0; + rtl::OUStringBuffer queryBuf(128); + queryBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT oid,typtype,typname FROM pg_TYPE WHERE " ) ); + while( rs->next() ) + { + if( row->getString( 9 ).equalsAscii( "d" ) && oidMap.find( row->getInt( 12 ) ) == oidMap.end() ) + { + oidMap[row->getInt(12)] = DatabaseTypeDescription(); + if( domains ) + queryBuf.appendAscii( " OR " ); + queryBuf.appendAscii( "oid = " ); + queryBuf.append( row->getInt(12 ), 10 ); + domains ++; + } + } + rs->beforeFirst(); + + if( domains ) + { + Reference< XResultSet > rsDomain = stmt->executeQuery( queryBuf.makeStringAndClear() ); + row = Reference< XRow >( rsDomain, UNO_QUERY ); + while( rsDomain->next() ) + { + oidMap[row->getInt(1)] = DatabaseTypeDescription(row->getString(3), row->getString(2) ); + } + disposeNoThrow( stmt ); + } + +} + + + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getColumns( + const ::com::sun::star::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& tableNamePattern, + const OUString& columnNamePattern ) throw (SQLException, RuntimeException) +{ + Statics &statics = getStatics(); + + // continue ! + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + rtl::OUStringBuffer buf( 128 ); + buf.appendAscii( "DatabaseMetaData::getColumns got called with " ); + buf.append( schemaPattern ); + buf.appendAscii( "." ); + buf.append( tableNamePattern ); + buf.appendAscii( "." ); + buf.append( columnNamePattern ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() ); + } + + // ignore catalog, as a single pq connection + // does not support multiple catalogs eitherway + + // 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_attribure.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_attribute.atttypmod + // 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 +// select objoid,description,objsubid,pg_attribute.attname from pg_attribute LEFT JOIN pg_description ON pg_attribute.attrelid=pg_description.objoid and pg_attribute.attnum = pg_description.objsubid + + Reference< XPreparedStatement > statement = m_origin->prepareStatement( + ASCII_STR( + + "SELECT pg_namespace.nspname, " // 1 + "pg_class.relname, " // 2 + "pg_attribute.attname, " // 3 + "pg_type.typname, " // 4 + "pg_attribute.atttypmod, " // 5 + "pg_attribute.attnotnull, " // 6 + "pg_type.typdefault, " // 7 + "pg_attribute.attnum, " // 8 + "pg_type.typtype, " // 9 + "pg_attrdef.adsrc, " // 10 + "pg_description.description, " // 11 + "pg_type.typbasetype " // 12 + "FROM pg_class, " + "pg_attribute LEFT JOIN pg_attrdef ON pg_attribute.attrelid = pg_attrdef.adrelid AND pg_attribute.attnum = pg_attrdef.adnum " + "LEFT JOIN pg_description ON pg_attribute.attrelid = pg_description.objoid AND pg_attribute.attnum=pg_description.objsubid," + " pg_type, pg_namespace " + "WHERE pg_attribute.attrelid = pg_class.oid " + "AND pg_attribute.atttypid = pg_type.oid " + "AND pg_class.relnamespace = pg_namespace.oid " + "AND pg_namespace.nspname LIKE ? " + "AND pg_class.relname LIKE ? " + "AND pg_attribute.attname LIKE ? " + "ORDER BY pg_namespace.nspname || pg_class.relname || pg_attribute.attnum" + ) ); + + Reference< XParameters > parameters( statement, UNO_QUERY ); + parameters->setString( 1 , schemaPattern ); + parameters->setString( 2 , tableNamePattern ); + parameters->setString( 3 , columnNamePattern ); + + Reference< XResultSet > rs = statement->executeQuery(); + Reference< XRow > xRow( rs, UNO_QUERY ); + SequenceAnyVector vec; + + Oid2DatabaseTypeDescriptionMap domainMap; + Reference< XStatement > domainTypeStmt = m_origin->createStatement(); + columnMetaData2DatabaseTypeDescription( domainMap, rs, domainTypeStmt ); + + while( rs->next() ) + { + OUString columnName = xRow->getString(3); + if( m_pSettings->showSystemColumns || ! isSystemColumn( columnName ) ) + { + sal_Int32 precision, scale, type; + Sequence< Any > row( 18 ); + row[0] <<= m_pSettings->catalog; + row[1] <<= xRow->getString(1); // + row[2] <<= xRow->getString(2); + row[3] <<= columnName; + if( xRow->getString(9).equalsAscii( "d" ) ) + { + DatabaseTypeDescription desc( domainMap[xRow->getInt(12)] ); + type = typeNameToDataType( desc.typeName, desc.typeType ); + } + else + { + type = typeNameToDataType( xRow->getString(4), xRow->getString(9) ); + } + extractPrecisionAndScale( type, xRow->getInt(5) , &precision, &scale ); + row[4] <<= type; + row[5] <<= xRow->getString(4); + row[6] <<= precision; + row[8] <<= scale; + if( xRow->getBoolean( 6 ) && ! isSystemColumn(xRow->getString(3)) ) + { + row[10] <<= OUString::valueOf(com::sun::star::sdbc::ColumnValue::NO_NULLS); + row[17] <<= statics.NO; + } + else + { + row[10] <<= OUString::valueOf(com::sun::star::sdbc::ColumnValue::NULLABLE); + row[17] <<= statics.YES; + } + + row[11] <<= xRow->getString( 11 ); // comment + row[12] <<= xRow->getString(10); // COLUMN_DEF = pg_type.typdefault + row[15] <<= precision; + row[16] <<= xRow->getString(8) ; + + // no description in postgresql AFAIK + vec.push_back( row ); + } + } + Reference< XCloseable > closeable( statement, UNO_QUERY ); + if( closeable.is() ) + closeable->close(); + + return new SequenceResultSet( + m_refMutex, *this, statics.columnRowNames, + Sequence< Sequence< Any > > ( &vec[0],vec.size() ), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getColumnPrivileges( + const ::com::sun::star::uno::Any& catalog, + const OUString& schema, + const OUString& table, + const OUString& columnNamePattern ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new SequenceResultSet( + m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc ); +} + +static void addPrivilegesToVector( + sal_Int32 privilege, const OUString &catalog, const OUString & schema, + const OUString &tableName, const OUString &grantor, const OUString &grantee, + bool grantable, SequenceAnyVector &vec ) +{ + Statics & statics = getStatics(); + for( int index = 1; index <= PRIVILEGE_MAX ; index = index << 1 ) + { + OUString privname; + switch( privilege & index ) + { + case PRIVILEGE_SELECT: + privname = statics.SELECT; break; + case PRIVILEGE_UPDATE: + privname = statics.UPDATE; break; + case PRIVILEGE_INSERT: + privname = statics.INSERT; break; + case PRIVILEGE_DELETE: + privname = statics.DELETE; break; + case PRIVILEGE_RULE: + privname = statics.RULE; break; + case PRIVILEGE_REFERENCES: + privname = statics.REFERENCES; break; + case PRIVILEGE_TRIGGER: + privname = statics.TRIGGER; break; + case PRIVILEGE_EXECUTE: + privname = statics.EXECUTE; break; + case PRIVILEGE_USAGE: + privname = statics.USAGE; break; + case PRIVILEGE_CREATE: + privname = statics.CREATE; break; + case PRIVILEGE_TEMPORARY: + privname = statics.TEMPORARY; break; + default: + break; + } + + Sequence< Any > seq( 7 ); + seq[0] <<= catalog; + seq[1] <<= schema; + seq[2] <<= tableName; + seq[3] <<= grantor; + seq[4] <<= grantee; + seq[5] <<= privname; + seq[6] <<= (grantable ? statics.YES : statics.NO ); + vec.push_back( seq ); + } +} + + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getTablePrivileges( + const ::com::sun::star::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& tableNamePattern ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + rtl::OUStringBuffer buf( 128 ); + buf.appendAscii( "DatabaseMetaData::getTablePrivileges got called with " ); + buf.append( schemaPattern ); + buf.appendAscii( "." ); + buf.append( tableNamePattern ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() ); + } + + // algorithm + + // get the pg_class.relact item for the concrete table + // get userid for username from pg_shadow (or pg_user view) + // get the group names mentioned in pg_class.relact from pg_group + // identify, which groups the current user belongs to + // calculate the union of all permissions (1 public, 1 user, n groups) + + // 1. TABLE_CAT string => table catalog (may be NULL ) + // 2. TABLE_SCHEM string => table schema (may be NULL ) + // 3. TABLE_NAME string => table name + // 4. GRANTOR => grantor of access (may be NULL ) + // 5. GRANTEE string => grantee of access + // 6. PRIVILEGE string => name of access (SELECT, INSERT, UPDATE, REFERENCES, ...) + // 7. IS_GRANTABLE string => "YES" if grantee is permitted to grant to + // others; "NO" if not; NULL if unknown + + Reference< XPreparedStatement > statement = m_origin->prepareStatement( + ASCII_STR( + "SELECT pg_namespace.nspname, " + "pg_class.relname, " + "pg_class.relacl, " + "pg_user.usename " + "FROM pg_class, pg_user, pg_namespace " + "WHERE pg_class.relowner = pg_user.usesysid " + "AND ( pg_class.relkind = 'r' OR pg_class.relkind = 'v' ) " + "AND pg_class.relnamespace = pg_namespace.oid " + "AND pg_namespace.nspname LIKE ? " + "AND pg_class.relname LIKE ?" + "ORDER BY pg_namespace.nspname || pg_class.relname " + ) ); + + Reference< XParameters > parameters( statement, UNO_QUERY ); + parameters->setString( 1 , schemaPattern ); + parameters->setString( 2 , tableNamePattern ); + + Reference< XResultSet > rs = statement->executeQuery(); + Reference< XRow > xRow( rs, UNO_QUERY ); + SequenceAnyVector vec; + while( rs->next() ) + { + // TODO calculate privileges ! + sal_Int32 privilege = 0; + privilege = + PRIVILEGE_SELECT | PRIVILEGE_UPDATE | PRIVILEGE_INSERT | + PRIVILEGE_DELETE | PRIVILEGE_RULE | PRIVILEGE_REFERENCES | + PRIVILEGE_TRIGGER| PRIVILEGE_EXECUTE| PRIVILEGE_USAGE | + PRIVILEGE_CREATE |PRIVILEGE_TEMPORARY; + + addPrivilegesToVector( privilege, + m_pSettings->catalog, + xRow->getString( 1 ), + xRow->getString( 2 ), + xRow->getString( 4 ), + m_pSettings->user, + m_pSettings->user == xRow->getString( 4 ), + vec ); + } + + return new SequenceResultSet( + m_refMutex, *this, getStatics().tablePrivilegesNames, + Sequence< Sequence< Any > > ( &vec[0], vec.size() ), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getBestRowIdentifier( + const ::com::sun::star::uno::Any& catalog, + const OUString& schema, + const OUString& table, + sal_Int32 scope, + sal_Bool nullable ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new SequenceResultSet( + m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getVersionColumns( + const ::com::sun::star::uno::Any& catalog, + const OUString& schema, + const OUString& table ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new SequenceResultSet( + m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getPrimaryKeys( + const ::com::sun::star::uno::Any& catalog, + const OUString& schema, + const OUString& table ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + +// 1. TABLE_CAT string => table catalog (may be NULL ) +// 2. TABLE_SCHEM string => table schema (may be NULL ) +// 3. TABLE_NAME string => table name +// 4. COLUMN_NAME string => column name +// 5. KEY_SEQ short => sequence number within primary key +// 6. PK_NAME string => primary key name (may be NULL ) + + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + rtl::OUStringBuffer buf( 128 ); + buf.appendAscii( "DatabaseMetaData::getPrimaryKeys got called with " ); + buf.append( schema ); + buf.appendAscii( "." ); + buf.append( table ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() ); + } + + Reference< XPreparedStatement > statement = m_origin->prepareStatement( + ASCII_STR( + "SELECT nmsp.nspname, " + "cl.relname, " + "con.conkey, " + "con.conname, " + "con.conrelid " + "FROM pg_constraint as con,pg_class as cl, pg_namespace as nmsp " + "WHERE con.connamespace = nmsp.oid AND con.conrelid = cl.oid AND con.contype = 'p' " + "AND nmsp.nspname LIKE ? AND cl.relname LIKE ?" ) ); + + Reference< XParameters > parameters( statement, UNO_QUERY ); + parameters->setString( 1 , schema ); + parameters->setString( 2 , table ); + + Reference< XResultSet > rs = statement->executeQuery(); + Reference< XRow > xRow( rs, UNO_QUERY ); + SequenceAnyVector vec; + + while( rs->next() ) + { + Sequence< Any > row( 6 ); + row[0] <<= m_pSettings->catalog; + row[1] <<= xRow->getString(1); // + row[2] <<= xRow->getString(2); + OUString array = xRow->getString(3); + row[4] <<= xRow->getString(5); // the relid + row[5] <<= xRow->getString(4); + + int i = 0; + // now retrieve the columns information + // unfortunately, postgresql does not allow array of variable size in + // WHERE clauses (in the default installation), so we have to choose + // this expensive and somewhat ugly way + // annotation: postgresql shouldn't have choosen an array here, instead they + // should have multiple rows per table + while( array[i] && '}' != array[i] ) + { + i++; + int start = i; + while( array[i] && array[i] != '}' && array[i] != ',' ) i++; + row[3] <<= OUString( &array[start], i - start ); + vec.push_back( row ); + } + } + + Reference< XCloseable > closeable( statement, UNO_QUERY ); + if( closeable.is() ) + closeable->close(); + + + SequenceAnyVector::iterator ii = vec.begin(); + OUString lastTableOid; + sal_Int32 index; + Sequence< Sequence< Any > > ret( vec.size() ); + int elements = 0; + for( ; ii != vec.end() ; ++ ii ) + { + + Sequence< Any > row = *ii; + OUString tableOid; + OUString attnum; + + row[4] >>= tableOid; + row[3] >>= attnum; + statement = m_origin->prepareStatement( + ASCII_STR( + "SELECT att.attname FROM " + "pg_attribute AS att, pg_class AS cl WHERE " + "att.attrelid = ? AND att.attnum = ?" )); + + parameters = Reference< XParameters >( statement, UNO_QUERY ); + parameters->setString( 1 , tableOid ); + parameters->setString( 2 , attnum ); + + rs = statement->executeQuery(); + xRow = Reference< XRow >( rs, UNO_QUERY ); + if( rs->next() ) + { + // column name + row[3] <<= xRow->getString( 1 ); + if( tableOid != lastTableOid ) + index = 1; + lastTableOid = tableOid; + row[4] <<= OUString::valueOf( index ); + index ++; + } + Reference< XCloseable > closeable( statement, UNO_QUERY ); + if( closeable.is() ) + closeable->close(); + ret[elements] = row; + elements ++; + } + return new SequenceResultSet( + m_refMutex, *this, getStatics().primaryKeyNames, ret , m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getImportedKeys( + const ::com::sun::star::uno::Any& catalog, + const OUString& schema, + const OUString& table ) throw (SQLException, RuntimeException) +{ +// MutexGuard guard( m_refMutex->mutex ); +// checkClosed(); + +// Statics &st = getStatics(); +// Int2StringMap mainMap; +// fillAttnum2attnameMap( mainMap, m_origin, m_schemaName, m_tableName ); + +// Reference< XPreparedStatement > stmt = m_origin->prepareStatement( +// ASCII_STR( +// "SELECT conname, " // 1 +// "confupdtype, " // 2 +// "confdeltype, " // 3 +// "class2.relname, " // 4 +// "nmsp2.nspname, " // 5 +// "conkey," // 6 +// "confkey " // 7 +// "FROM pg_constraint INNER JOIN pg_class ON conrelid = pg_class.oid " +// "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid " +// "LEFT JOIN pg_class AS class2 ON confrelid = class2.oid " +// "LEFT JOIN pg_namespace AS nmsp2 ON class2.relnamespace=nmsp2.oid " +// "WHERE pg_class.relname = ? AND " +// "pg_namespace.nspname = ? " +// "AND contype = 'f'")); + +// Reference< XResultSet > rs = stmt->executeQuery(); +// Reference< XRow > row( rs, UNO_QUERY ); +// while( rs->next() ) +// { + +// static const PKTABLE_CAT = 0; +// static const PKTABLE_SCHEM = 1; +// static const PKTABLE_NAME = 2; +// static const PKCOLUMN_NAME = 3; +// static const FKTABLE_CAT = 4; +// static const FKTABLE_SCHEM = 5; +// static const FKTABLE_NAME = 6; +// static const FKCOLUMN_NAME = 7; +// static const KEY_SEQ = 8; +// static const UPDATE_RULE = 9; +// static const DELETE_RULE = 10; +// static const FK_NAME = 11; +// static const PK_NAME = 12; +// static const DEFERRABILITY = 13; + +// OUString pkSchema = xRow->getString(6); +// OUString pkTable = xRow->getString(5); + +// Int2StringMap foreignMap; +// fillAttnum2attnameMap( foreignMap, m_origin,pkSchema, pkTable); + +// Sequence< rtl::OUString > pkColNames = +// convertMappedIntArray2StringArray( +// foreignMap, string2intarray( row->getString( 7 ) ) ); +// Sequence< rtl::OUString > fkColNames = +// convertMappedIntArray2StringArray( +// mainMap, string2intarray( row->getString( 6 ) ) ); + +// for( sal_Int32 i = 0 ; i < pkColNames.getLength() ; i ++ ) +// { +// Sequence< Any > theRow( 14 ); + +// theRow[PKTABLE_SCHEM] = makeAny( pkSchema ); +// theRow[PKTABLE_NAME] = makeAny( pkTable ); +// theRow[PKCOLUMN_NAME] = makeAny( pkColNames[i] ); +// theRow[FKTABLE_SCHEM] = makeAny( schema ); +// theRow[FKTABLE_NAME] = makeAny( table ); +// theRow[FKCOLUMN_NAME] = makeAny( fkColNames[i] ); +// theRow[KEY_SEQ] = makeAny( OUString::valueOf( i ) ); +// theRow[ + + +// pKey->setPropertyValue_NoBroadcast_public( +// st.PRIVATE_FOREIGN_COLUMNS, +// makeAny( resolveColumnNames(foreignMap, xRow->getString(8) ) ) ); + +// } + // fake the getImportedKey() function call in + // dbaccess/source/ui/relationdesigin/RelationController.cxx + // it seems to be the only place in the office, where this function is needed + return new SequenceResultSet( + m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (1), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getExportedKeys( + const ::com::sun::star::uno::Any& catalog, + const OUString& schema, + const OUString& table ) throw (SQLException, RuntimeException) +{ + throw ::com::sun::star::sdbc::SQLException( + ASCII_STR( "pq_databasemetadata: imported keys from tables not supported " ), + *this, + OUString(), 1, Any() ); +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getCrossReference( + const ::com::sun::star::uno::Any& primaryCatalog, + const OUString& primarySchema, + const OUString& primaryTable, + const ::com::sun::star::uno::Any& foreignCatalog, + const OUString& foreignSchema, + const OUString& foreignTable ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new SequenceResultSet( + m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc ); +} + + +struct TypeInfoByDataTypeSorter +{ + bool operator () ( const Sequence< Any > & a, const Sequence< Any > & b ) + { + OUString valueA; + OUString valueB; + a[1 /*DATA_TYPE*/] >>= valueA; + b[1 /*DATA_TYPE*/] >>= valueB; + if( valueB.toInt32() == valueA.toInt32() ) + { + OUString nameA; + OUString nameB; + a[0 /*TYPE_NAME*/] >>= nameA; + b[0 /*TYPE_NAME*/] >>= nameB; + if( nameA.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "int4" ) ) == 0 ) + return 1; + if( nameB.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "int4" ) ) == 0 ) + return 0; + return nameA.compareTo( nameB ) < 0; + } + + return valueA.toInt32() < valueB.toInt32(); +// sal_Int32 valueA; +// sal_Int32 valueB; +// a[1 /*DATA_TYPE*/] >>= valueA; +// b[1 /*DATA_TYPE*/] >>= valueB; +// if( valueB == valueA ) +// { +// OUString nameA; +// OUString nameB; +// a[0 /*TYPE_NAME*/] >>= nameA; +// b[0 /*TYPE_NAME*/] >>= nameB; +// return nameA.compareTo( nameB ) < 0; +// } + +// return valueA < valueB; + } +}; + +static sal_Int32 calcSearchable( sal_Int32 dataType ) +{ + sal_Int32 ret = com::sun::star::sdbc::ColumnSearch::FULL; + if( com::sun::star::sdbc::DataType::BINARY == dataType || + com::sun::star::sdbc::DataType::VARBINARY == dataType || + com::sun::star::sdbc::DataType::LONGVARBINARY == dataType ) + sal_Int32 ret = com::sun::star::sdbc::ColumnSearch::NONE; + + return ret; +} + +static sal_Int32 getMaxScale( sal_Int32 dataType ) +{ + sal_Int32 ret = 0; + if( dataType == com::sun::star::sdbc::DataType::NUMERIC ) + ret = 1000; // see pg-docs DataType/numeric +// else if( dataType == DataType::DOUBLE ) +// ret = 308; +// else if( dataType == DataType::FLOAT ) +// ret = + return ret; +} + + +struct RawType +{ + const char * typeName; + const char * createParam; + sal_Int32 sdbcType; + sal_Int32 precision; + sal_Int32 nullable; + bool caseSensitive; + sal_Int32 searchable; +}; + +static void pgTypeInfo2ResultSet( + SequenceAnyVector &vec, + const Reference< XResultSet > &rs ) +{ + static const sal_Int32 TYPE_NAME = 0; // string Type name + static const sal_Int32 DATA_TYPE = 1; // short SQL data type from java.sql.Types + static const sal_Int32 PRECISION = 2; // long maximum precision + static const sal_Int32 CREATE_PARAMS = 5; // string => parameters used in creating the type (may be NULL ) + static const sal_Int32 NULLABLE = 6; // short ==> can you use NULL for this type? + // - NO_NULLS - does not allow NULL values + // - NULLABLE - allows NULL values + // - NULLABLE_UNKNOWN - nullability unknown + + static const sal_Int32 CASE_SENSITIVE = 7; // boolean==> is it case sensitive + static const sal_Int32 SEARCHABLE = 8; // short ==>; can you use + // "WHERE" based on this type: + // - NONE - No support + // - CHAR - Only supported with WHERE .. LIKE + // - BASIC - Supported except for WHERE .. LIKE + // - FULL - Supported for all WHERE .. + static const sal_Int32 UNSIGNED_ATTRIBUTE = 9; // boolean ==> is it unsigned? + static const sal_Int32 FIXED_PREC_SCALE = 10; // boolean ==> can it be a money value? + static const sal_Int32 AUTO_INCREMENT = 11; // boolean ==> can it be used for + // an auto-increment value? + static const sal_Int32 MINIMUM_SCALE = 13; // short ==> minimum scale supported + static const sal_Int32 MAXIMUM_SCALE = 14; // short ==> maximum scale supported + static const sal_Int32 NUM_PREC_RADIX = 17; // long ==> usually 2 or 10 + + /* not filled so far + 3. LITERAL_PREFIX string ==> prefix used to quote a literal + (may be ) + 4, LITERAL_SUFFIX string ==> suffix used to quote a literal + (may be ) + 5. CREATE_PARAMS string ==> parameters used in creating thw type (may be ) + 12. LOCAL_TYPE_NAME string ==> localized version of type name (may be ) + 15, SQL_DATA_TYPE long ==> unused + 16. SQL_DATETIME_SUB long ==> unused + */ + Reference< XRow > xRow( rs, UNO_QUERY ); + while( rs->next() ) + { + Sequence< Any > row(18); + + sal_Int32 dataType =typeNameToDataType(xRow->getString(5),xRow->getString(2)); + sal_Int32 precision = xRow->getString(3).toInt32(); + + if( dataType == com::sun::star::sdbc::DataType::CHAR || + dataType == com::sun::star::sdbc::DataType::VARCHAR && + xRow->getString(TYPE_NAME+1).equalsIgnoreAsciiCaseAscii( "varchar") ) + { + // reflect varchar as varchar with upper limit ! + //NOTE: the sql spec requires varchar to have an upper limit, however + // in postgresql the upper limit is optional, no limit means unlimited + // length (=1GB). + precision = 0x40000000; // about 1 GB, see character type docs in postgresql + row[CREATE_PARAMS] <<= ASCII_STR( "length" ); + } + else if( dataType == com::sun::star::sdbc::DataType::NUMERIC ) + { + precision = 1000; + row[CREATE_PARAMS] <<= ASCII_STR( "length, scale" ); + } + + row[TYPE_NAME] <<= xRow->getString(1); + row[DATA_TYPE] <<= OUString::valueOf(dataType); + row[PRECISION] <<= OUString::valueOf( precision ); + sal_Int32 nullable = xRow->getBoolean(4) ? + com::sun::star::sdbc::ColumnValue::NO_NULLS : + com::sun::star::sdbc::ColumnValue::NULLABLE; + row[NULLABLE] <<= OUString::valueOf(nullable); + row[CASE_SENSITIVE] <<= OUString::valueOf((sal_Int32)1); + row[SEARCHABLE] <<= OUString::valueOf( calcSearchable( dataType ) ); + row[UNSIGNED_ATTRIBUTE] <<= ASCII_STR( "0" ); // + if( com::sun::star::sdbc::DataType::INTEGER == dataType || + com::sun::star::sdbc::DataType::BIGINT == dataType ) + row[AUTO_INCREMENT] <<= ASCII_STR( "1" ); // TODO + else + row[AUTO_INCREMENT] <<= ASCII_STR( "0" ); // TODO + row[MINIMUM_SCALE] <<= ASCII_STR( "0" ); // TODO: what is this ? + row[MAXIMUM_SCALE] <<= OUString::valueOf( getMaxScale( dataType ) ); + row[NUM_PREC_RADIX] <<= ASCII_STR( "10" ); // TODO: what is this ? + vec.push_back( row ); + } + +} + + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getTypeInfo( ) + throw (SQLException, RuntimeException) +{ + // Note: Indexes start at 0 (in the API doc, they start at 1) + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + log( m_pSettings, LogLevel::INFO, "DatabaseMetaData::getTypeInfo() got called" ); + } + + Reference< XStatement > statement = m_origin->createStatement(); + Reference< XResultSet > rs = statement->executeQuery( + ASCII_STR( + "SELECT pg_type.typname AS typname," //1 + "pg_type.typtype AS typtype," //2 + "pg_type.typlen AS typlen," //3 + "pg_type.typnotnull AS typnotnull," //4 + "pg_type.typname AS typname " //5 + "FROM pg_type " + "WHERE pg_type.typtype = 'b' " + "OR pg_type.typtype = 'p'" + ) ); + + SequenceAnyVector vec; + pgTypeInfo2ResultSet( vec, rs ); + + // check for domain types + rs = statement->executeQuery( + ASCII_STR( + "SELECT t1.typname as typname," + "t2.typtype AS typtype," + "t2.typlen AS typlen," + "t2.typnotnull AS typnotnull," + "t2.typname as realtypname " + "FROM pg_type as t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype=t2.oid " + "WHERE t1.typtype = 'd'" ) ); + pgTypeInfo2ResultSet( vec, rs ); + + std::sort( vec.begin(), vec.end(), TypeInfoByDataTypeSorter() ); + + return new SequenceResultSet( + m_refMutex, + *this, + getStatics().typeinfoColumnNames, + Sequence< Sequence< Any > > ( &vec[0] , vec.size() ), + m_pSettings->tc, + &( getStatics().typeInfoMetaData )); +} + + +static sal_Int32 seqContains( const Sequence< sal_Int32 > &seq, sal_Int32 value ) +{ + sal_Int32 ret = -1; + for( int i = 0; i < seq.getLength(); i ++ ) + { + if( seq[i] == value ) + { + ret = i; + break; + } + } + return ret; +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getIndexInfo( + const ::com::sun::star::uno::Any& catalog, + const OUString& schema, + const OUString& table, + sal_Bool unique, + sal_Bool approximate ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + + /* + 1. TABLE_CAT string -> table catalog (may be NULL ) + 2. TABLE_SCHEM string -> table schema (may be NULL ) + 3. TABLE_NAME string -> table name + 4. NON_UNIQUE boolean -> Can index values be non-unique? + false when TYPE is tableIndexStatistic + 5. INDEX_QUALIFIER string -> index catalog (may be NULL ); + NULL when TYPE is tableIndexStatistic + 6. INDEX_NAME string -> index name; NULL when TYPE is tableIndexStatistic + 7. TYPE short -> index type: + * 0 - this identifies table statistics that are returned + in conjuction with a table's index descriptions + * CLUSTERED - this is a clustered index + * HASHED - this is a hashed index + * OTHER - this is some other style of index + 8. ORDINAL_POSITION short -> column sequence number within index; + zero when TYPE is tableIndexStatistic + 9. COLUMN_NAME string -> column name; NULL when TYPE is tableIndexStatistic + 10. ASC_OR_DESC string -> column sort sequence, "A"= ascending, + "D" = descending, may be NULL if sort sequence + is not supported; NULL when TYPE is tableIndexStatistic + 11. CARDINALITY long -> When TYPE is tableIndexStatistic, then this is + the number of rows in the table; otherwise, it + is the number of unique values in the index. + 12. PAGES long -> When TYPE is tableIndexStatisic then this is + the number of pages used for the table, otherwise + it is the number of pages used for the current index. + 13. FILTER_CONDITION string -> Filter condition, if any. (may be NULL ) + + */ + static const sal_Int32 C_SCHEMA = 1; + static const sal_Int32 C_TABLENAME = 2; + static const sal_Int32 C_INDEXNAME = 3; + static const sal_Int32 C_IS_CLUSTERED = 4; + static const sal_Int32 C_IS_UNIQUE = 5; + static const sal_Int32 C_IS_PRIMARY = 6; + static const sal_Int32 C_COLUMNS = 7; + + static const sal_Int32 R_TABLE_SCHEM = 1; + static const sal_Int32 R_TABLE_NAME = 2; + static const sal_Int32 R_NON_UNIQUE = 3; + static const sal_Int32 R_INDEX_NAME = 5; + static const sal_Int32 R_TYPE = 6; + static const sal_Int32 R_ORDINAL_POSITION = 7; + static const sal_Int32 R_COLUMN_NAME = 8; + + Reference< XPreparedStatement > stmt = m_origin->prepareStatement( + ASCII_STR( + "SELECT nspname, " // 1 + "pg_class.relname, " // 2 + "class2.relname, " // 3 + "indisclustered, " // 4 + "indisunique, " // 5 + "indisprimary, " // 6 + "indkey " // 7 + "FROM pg_index INNER JOIN pg_class ON indrelid = pg_class.oid " + "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid " + "INNER JOIN pg_class as class2 ON pg_index.indexrelid = class2.oid " + "WHERE nspname = ? AND pg_class.relname = ?" ) ); + + Reference< XParameters > param ( stmt, UNO_QUERY ); + param->setString( 1, schema ); + param->setString( 2, table ); + Reference< XResultSet > rs = stmt->executeQuery(); + Reference< XRow > xRow ( rs, UNO_QUERY ); + + SequenceAnyVector vec; + while( rs->next() ) + { + Sequence< sal_Int32 > columns = parseIntArray( xRow->getString(C_COLUMNS) ); + Reference< XPreparedStatement > columnsStmt = m_origin->prepareStatement( + ASCII_STR( + "SELECT attnum, attname " + "FROM pg_attribute " + " INNER JOIN pg_class ON attrelid = pg_class.oid " + " INNER JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid " + " WHERE pg_namespace.nspname=? AND pg_class.relname=?" ) ); + Reference< XParameters > paramColumn ( columnsStmt, UNO_QUERY ); + OUString currentSchema = xRow->getString( C_SCHEMA ); + OUString currentTable = xRow->getString( C_TABLENAME ); + OUString currentIndexName = xRow->getString( C_INDEXNAME ); + sal_Bool isNonUnique = ! xRow->getBoolean( C_IS_UNIQUE ); + sal_Bool isPrimary = xRow->getBoolean( C_IS_PRIMARY ); + sal_Int32 indexType = xRow->getBoolean( C_IS_CLUSTERED ) ? + com::sun::star::sdbc::IndexType::CLUSTERED : + com::sun::star::sdbc::IndexType::HASHED; + + paramColumn->setString( C_SCHEMA, currentSchema ); + paramColumn->setString( C_TABLENAME, currentTable ); + + Reference< XResultSet > rsColumn = columnsStmt->executeQuery(); + Reference< XRow > rowColumn( rsColumn, UNO_QUERY ); + while( rsColumn->next() ) + { + sal_Int32 pos = seqContains( columns, rowColumn->getInt( 1 ) ); + if( pos >= 0 && ( ! isNonUnique || ! unique ) ) + { + Sequence< Any > result( 13 ); + result[R_TABLE_SCHEM] = makeAny(currentSchema); + result[R_TABLE_NAME] = makeAny(currentTable); + result[R_INDEX_NAME] = makeAny(currentIndexName); + result[R_NON_UNIQUE] = + Any( &isNonUnique, getBooleanCppuType() ); + result[R_TYPE] = makeAny( indexType ); + result[R_COLUMN_NAME] = makeAny( rowColumn->getString(2) ); + sal_Int32 nPos = ((sal_Int32)pos+1); // MSVC++ nonsense + result[R_ORDINAL_POSITION] = makeAny( nPos ); + vec.push_back( result ); + } + } + } + return new SequenceResultSet( + m_refMutex, *this, getStatics().indexinfoColumnNames, + Sequence< Sequence< Any > > ( &vec[0] , vec.size() ), + m_pSettings->tc ); +} + +sal_Bool DatabaseMetaData::supportsResultSetType( sal_Int32 setType ) + throw (SQLException, RuntimeException) +{ + return + setType == com::sun::star::sdbc::ResultSetType::SCROLL_INSENSITIVE || + setType == com::sun::star::sdbc::ResultSetType::FORWARD_ONLY; +} + +sal_Bool DatabaseMetaData::supportsResultSetConcurrency( + sal_Int32 setType, sal_Int32 concurrency ) throw (SQLException, RuntimeException) +{ + return supportsResultSetType( setType ) && + (concurrency == com::sun::star::sdbc::TransactionIsolation::READ_COMMITTED || + concurrency == com::sun::star::sdbc::TransactionIsolation::SERIALIZABLE ); +} + +sal_Bool DatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::updatesAreDetected( sal_Int32 setType ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::deletesAreDetected( sal_Int32 setType ) throw (SQLException, RuntimeException) +{ + return sal_False; +} +sal_Bool DatabaseMetaData::insertsAreDetected( sal_Int32 setType ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool DatabaseMetaData::supportsBatchUpdates( ) throw (SQLException, RuntimeException) +{ + return sal_False; +} + +::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getUDTs( const ::com::sun::star::uno::Any& catalog, const OUString& schemaPattern, const OUString& typeNamePattern, const ::com::sun::star::uno::Sequence< sal_Int32 >& types ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new SequenceResultSet( + m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc ); +} + +::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > DatabaseMetaData::getConnection() + throw (SQLException, RuntimeException) +{ + return m_origin; +} +} diff --git connectivity/source/drivers/postgresql/pq_databasemetadata.hxx connectivity/source/drivers/postgresql/pq_databasemetadata.hxx new file mode 100644 index 0000000..b5dea7d --- /dev/null +++ connectivity/source/drivers/postgresql/pq_databasemetadata.hxx @@ -0,0 +1,244 @@ +/************************************************************************* + * + * $RCSfile: pq_databasemetadata.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2003/06/03 21:48:28 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_DATABASEMETADATA_HXX_ +#define _PQ_DATABASEMETADATA_HXX_ + +#include "pq_connection.hxx" +#include + +#include + +namespace pq_sdbc_driver +{ + +class DatabaseMetaData : + public ::cppu::WeakImplHelper1 < com::sun::star::sdbc::XDatabaseMetaData > +{ + ::rtl::Reference< RefCountedMutex > m_refMutex; + ConnectionSettings *m_pSettings; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_origin; + + void checkClosed() + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); +public: + DatabaseMetaData( + const ::rtl::Reference< RefCountedMutex > & reMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings + ); + +public: + // Methods + virtual sal_Bool SAL_CALL allProceduresAreCallable( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL allTablesAreSelectable( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getURL( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getUserName( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isReadOnly( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL nullsAreSortedHigh( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL nullsAreSortedLow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL nullsAreSortedAtStart( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL nullsAreSortedAtEnd( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDatabaseProductName( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDatabaseProductVersion( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDriverName( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDriverVersion( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getDriverMajorVersion( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getDriverMinorVersion( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL usesLocalFiles( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL usesLocalFilePerTable( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsMixedCaseIdentifiers( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL storesUpperCaseIdentifiers( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL storesLowerCaseIdentifiers( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL storesMixedCaseIdentifiers( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsMixedCaseQuotedIdentifiers( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL storesUpperCaseQuotedIdentifiers( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL storesLowerCaseQuotedIdentifiers( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL storesMixedCaseQuotedIdentifiers( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getIdentifierQuoteString( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSQLKeywords( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getNumericFunctions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getStringFunctions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSystemFunctions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTimeDateFunctions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSearchStringEscape( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getExtraNameCharacters( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsAlterTableWithAddColumn( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsAlterTableWithDropColumn( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsColumnAliasing( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL nullPlusNonNullIsNull( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsTypeConversion( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsConvert( sal_Int32 fromType, sal_Int32 toType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsTableCorrelationNames( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsDifferentTableCorrelationNames( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsExpressionsInOrderBy( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsOrderByUnrelated( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsGroupBy( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsGroupByUnrelated( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsGroupByBeyondSelect( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsLikeEscapeClause( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsMultipleResultSets( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsMultipleTransactions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsNonNullableColumns( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsMinimumSQLGrammar( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsCoreSQLGrammar( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsExtendedSQLGrammar( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsANSI92EntryLevelSQL( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsANSI92IntermediateSQL( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsANSI92FullSQL( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsIntegrityEnhancementFacility( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsOuterJoins( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsFullOuterJoins( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsLimitedOuterJoins( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSchemaTerm( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getProcedureTerm( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getCatalogTerm( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isCatalogAtStart( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getCatalogSeparator( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSchemasInDataManipulation( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSchemasInProcedureCalls( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSchemasInTableDefinitions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSchemasInIndexDefinitions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSchemasInPrivilegeDefinitions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsCatalogsInDataManipulation( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsCatalogsInProcedureCalls( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsCatalogsInTableDefinitions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsCatalogsInIndexDefinitions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsCatalogsInPrivilegeDefinitions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsPositionedDelete( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsPositionedUpdate( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSelectForUpdate( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsStoredProcedures( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSubqueriesInComparisons( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSubqueriesInExists( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSubqueriesInIns( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsSubqueriesInQuantifieds( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsCorrelatedSubqueries( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsUnion( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsUnionAll( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsOpenCursorsAcrossCommit( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsOpenCursorsAcrossRollback( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsOpenStatementsAcrossCommit( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsOpenStatementsAcrossRollback( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxBinaryLiteralLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxCharLiteralLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxColumnNameLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxColumnsInGroupBy( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxColumnsInIndex( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxColumnsInOrderBy( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxColumnsInSelect( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxColumnsInTable( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxConnections( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxCursorNameLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxIndexLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxSchemaNameLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxProcedureNameLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxCatalogNameLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxRowSize( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL doesMaxRowSizeIncludeBlobs( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxStatementLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxStatements( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxTableNameLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxTablesInSelect( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMaxUserNameLength( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getDefaultTransactionIsolation( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsTransactions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsTransactionIsolationLevel( sal_Int32 level ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsDataDefinitionAndDataManipulationTransactions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsDataManipulationTransactionsOnly( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL dataDefinitionCausesTransactionCommit( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL dataDefinitionIgnoredInTransactions( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getProcedures( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schemaPattern, const ::rtl::OUString& procedureNamePattern ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getProcedureColumns( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schemaPattern, const ::rtl::OUString& procedureNamePattern, const ::rtl::OUString& columnNamePattern ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getTables( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schemaPattern, const ::rtl::OUString& tableNamePattern, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& types ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getSchemas( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getCatalogs( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getTableTypes( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getColumns( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schemaPattern, const ::rtl::OUString& tableNamePattern, const ::rtl::OUString& columnNamePattern ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getColumnPrivileges( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schema, const ::rtl::OUString& table, const ::rtl::OUString& columnNamePattern ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getTablePrivileges( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schemaPattern, const ::rtl::OUString& tableNamePattern ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getBestRowIdentifier( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schema, const ::rtl::OUString& table, sal_Int32 scope, sal_Bool nullable ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getVersionColumns( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schema, const ::rtl::OUString& table ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getPrimaryKeys( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schema, const ::rtl::OUString& table ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getImportedKeys( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schema, const ::rtl::OUString& table ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getExportedKeys( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schema, const ::rtl::OUString& table ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getCrossReference( const ::com::sun::star::uno::Any& primaryCatalog, const ::rtl::OUString& primarySchema, const ::rtl::OUString& primaryTable, const ::com::sun::star::uno::Any& foreignCatalog, const ::rtl::OUString& foreignSchema, const ::rtl::OUString& foreignTable ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getTypeInfo( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getIndexInfo( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schema, const ::rtl::OUString& table, sal_Bool unique, sal_Bool approximate ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsResultSetType( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsResultSetConcurrency( sal_Int32 setType, sal_Int32 concurrency ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL ownUpdatesAreVisible( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL ownDeletesAreVisible( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL ownInsertsAreVisible( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL othersUpdatesAreVisible( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL othersDeletesAreVisible( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL othersInsertsAreVisible( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL updatesAreDetected( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL deletesAreDetected( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL insertsAreDetected( sal_Int32 setType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsBatchUpdates( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getUDTs( const ::com::sun::star::uno::Any& catalog, const ::rtl::OUString& schemaPattern, const ::rtl::OUString& typeNamePattern, const ::com::sun::star::uno::Sequence< sal_Int32 >& types ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL getConnection( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); +}; + +} + +#endif diff --git connectivity/source/drivers/postgresql/pq_driver.cxx connectivity/source/drivers/postgresql/pq_driver.cxx new file mode 100644 index 0000000..ad74c57 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_driver.cxx @@ -0,0 +1,406 @@ +/************************************************************************* + * + * $RCSfile: pq_driver.cxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/05/09 19:47:13 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "pq_driver.hxx" + +using rtl::OUString; +using rtl::OUStringToOString; +using osl::MutexGuard; + +using cppu::WeakComponentImplHelper2; + +using com::sun::star::lang::XSingleComponentFactory; +using com::sun::star::lang::XServiceInfo; +using com::sun::star::lang::XComponent; + +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Exception; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::XComponentContext; +using com::sun::star::uno::Any; + +using com::sun::star::beans::PropertyValue; +using com::sun::star::beans::XPropertySet; + +using com::sun::star::sdbc::XConnection; +using com::sun::star::sdbc::SQLException; +using com::sun::star::sdbc::DriverPropertyInfo; + +using com::sun::star::sdbcx::XTablesSupplier; + + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +OUString DriverGetImplementationName() +{ + static OUString *p; + if (! p ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + static OUString instance( + RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.connectivity.pq.Driver" ) ); + p = &instance; + } + return *p; +} + +Sequence< OUString > DriverGetSupportedServiceNames() +{ + static Sequence< OUString > *p; + if( ! p ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + OUString tmp( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.Driver" ) ); + static Sequence< OUString > instance( &tmp,1 ); + p = &instance; + } + return *p; +} + +Reference< XConnection > Driver::connect( + const OUString& url,const Sequence< PropertyValue >& info ) + throw (SQLException, RuntimeException) +{ + if( ! acceptsURL( url ) ) // XDriver spec tells me to do so ... + return Reference< XConnection > (); + + Sequence< Any > seq ( 2 ); + seq[0] <<= url; + seq[1] <<= info; + return Reference< XConnection> ( + m_smgr->createInstanceWithArgumentsAndContext( + OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.connectivity.pq.Connection" ) ), + seq, m_ctx ), + UNO_QUERY ); +} + +sal_Bool Driver::acceptsURL( const ::rtl::OUString& url ) + throw (SQLException, RuntimeException) +{ + return url.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "sdbc:postgresql:" ) ) == 0; +} + +Sequence< DriverPropertyInfo > Driver::getPropertyInfo( + const OUString& url,const Sequence< PropertyValue >& info ) + throw (SQLException, RuntimeException) +{ + return Sequence< DriverPropertyInfo > (); +} + +sal_Int32 Driver::getMajorVersion( ) throw (RuntimeException) +{ + return PQ_SDBC_MAJOR; +} + + +sal_Int32 Driver::getMinorVersion( ) throw (RuntimeException) +{ + return PQ_SDBC_MINOR; +} + + // XServiceInfo +OUString SAL_CALL Driver::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return DriverGetImplementationName(); +} + +sal_Bool Driver::supportsService(const OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException) +{ + Sequence< OUString > serviceNames = DriverGetSupportedServiceNames(); + for( int i = 0 ; i < serviceNames.getLength() ; i ++ ) + if( serviceNames[i] == ServiceName ) + return sal_True; + return sal_False; +} + +Sequence< OUString > Driver::getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException) +{ + return DriverGetSupportedServiceNames(); +} + +// XComponent +void Driver::disposing() +{ + +} + + +Reference< XTablesSupplier > Driver::getDataDefinitionByConnection( + const Reference< XConnection >& connection ) + throw (SQLException, RuntimeException) +{ + return Reference< XTablesSupplier >( connection , UNO_QUERY ); +} + +Reference< XTablesSupplier > Driver::getDataDefinitionByURL( + const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) + throw (SQLException, RuntimeException) +{ + return Reference< XTablesSupplier > ( connect( url, info ), UNO_QUERY ); +} + + +Reference< XInterface > DriverCreateInstance( const Reference < XComponentContext > & ctx ) +{ + Reference< XInterface > ret = * new Driver( ctx ); + return ret; +} + + + + +class OOneInstanceComponentFactory : + public MutexHolder, + public WeakComponentImplHelper2< XSingleComponentFactory, XServiceInfo > +{ +public: + OOneInstanceComponentFactory( + const OUString & rImplementationName_, + cppu::ComponentFactoryFunc fptr, + const Sequence< OUString > & serviceNames, + const Reference< XComponentContext > & defaultContext) : + WeakComponentImplHelper2< XSingleComponentFactory, XServiceInfo >( this->m_mutex ), + m_implName( rImplementationName_ ), + m_create( fptr ), + m_serviceNames( serviceNames ), + m_defaultContext( defaultContext ) + { + } + + // XSingleComponentFactory + virtual Reference< XInterface > SAL_CALL createInstanceWithContext( + Reference< XComponentContext > const & xContext ) + throw (Exception, RuntimeException); + virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( + Sequence< Any > const & rArguments, + Reference< XComponentContext > const & xContext ) + throw (Exception, RuntimeException); + + // XServiceInfo + OUString SAL_CALL getImplementationName() + throw(::com::sun::star::uno::RuntimeException) + { + return m_implName; + } + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException) + { + for( int i = 0 ; i < m_serviceNames.getLength() ; i ++ ) + if( m_serviceNames[i] == ServiceName ) + return sal_True; + return sal_False; + } + Sequence< OUString > SAL_CALL getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException) + { + return m_serviceNames; + } + + // XComponent + virtual void SAL_CALL disposing(); + +private: + cppu::ComponentFactoryFunc m_create; + Sequence< OUString > m_serviceNames; + OUString m_implName; + Reference< XInterface > m_theInstance; + Reference< XComponentContext > m_defaultContext; +}; + +Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithArgumentsAndContext( + Sequence< Any > const &rArguments, const Reference< XComponentContext > & ctx ) + throw( RuntimeException, Exception ) +{ + return createInstanceWithContext( ctx ); +} + +Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithContext( + const Reference< XComponentContext > & ctx ) + throw( RuntimeException, Exception ) +{ + if( ! m_theInstance.is() ) + { + // work around the problem in sdbc + Reference< XComponentContext > useCtx = ctx; + if( ! useCtx.is() ) + useCtx = m_defaultContext; + Reference< XInterface > theInstance = m_create( useCtx ); + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( ! m_theInstance.is () ) + { + m_theInstance = theInstance; + } + } + return m_theInstance; +} + +void OOneInstanceComponentFactory::disposing() +{ + Reference< XComponent > rComp; + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + rComp = Reference< XComponent >( m_theInstance, UNO_QUERY ); + m_theInstance.clear(); + } + if( rComp.is() ) + rComp->dispose(); +} + +// Reference< XSingleComponentFactory > createOneInstanceComponentFactory( +// cppu::ComponentFactoryFunc fptr, +// ::rtl::OUString const & rImplementationName, +// ::com::sun::star::uno::Sequence< ::rtl::OUString > const & rServiceNames, +// rtl_ModuleCount * pModCount = 0 ) +// SAL_THROW( () ) +// { +// return new OOneInstanceComponentFactory( rImplementationName, fptr , rServiceNames); +// } + +} + +static struct cppu::ImplementationEntry g_entries[] = +{ + { + pq_sdbc_driver::DriverCreateInstance, pq_sdbc_driver::DriverGetImplementationName, + pq_sdbc_driver::DriverGetSupportedServiceNames, 0, + 0 , 0 + }, + { 0, 0, 0, 0, 0, 0 } +}; + +extern "C" +{ + +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + return cppu::component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries ); +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + // need to extract the defaultcontext, because the way, sdbc + // bypasses the servicemanager, does not allow to use the + // XSingleComponentFactory interface ... + void * pRet = 0; + Reference< XSingleComponentFactory > xFactory; + Reference< XInterface > xSmgr( (XInterface * ) pServiceManager ); + + for( sal_Int32 i = 0 ; g_entries[i].create ; i ++ ) + { + OUString implName = g_entries[i].getImplementationName(); + if( 0 == implName.compareToAscii( pImplName ) ) + { + Reference< XComponentContext > defaultContext; + Reference< XPropertySet > propSet( xSmgr, UNO_QUERY ); + if( propSet.is() ) + { + try + { + propSet->getPropertyValue( ASCII_STR( "DefaultContext" ) ) >>= defaultContext; + } + catch( com::sun::star::uno::Exception &e ) + { + // if there is no default context, ignore it + } + } + xFactory = new pq_sdbc_driver::OOneInstanceComponentFactory( + implName, + g_entries[i].create, + g_entries[i].getSupportedServiceNames(), + defaultContext ); + } + } + + if( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + return pRet; +} + +} diff --git connectivity/source/drivers/postgresql/pq_driver.hxx connectivity/source/drivers/postgresql/pq_driver.hxx new file mode 100644 index 0000000..6151ce1 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_driver.hxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * $RCSfile: pq_driver.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/05/09 19:47:14 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#ifndef _PG_DRIVER_HXX_ +#define _PG_DRIVER_HXX_ + +#include + +#include +#include + +#include + +#include +#include + +#include + +namespace pq_sdbc_driver +{ + +#define MY_STRINGIFY( x ) #x + +#define PQ_SDBC_DRIVER_VERSION MY_STRINGIFY(PQ_SDBC_MAJOR) "." \ + MY_STRINGIFY(PQ_SDBC_MINOR) "." \ + MY_STRINGIFY(PQ_SDBC_MICRO) + +#define POSTGRES_MAJOR 7 +#define POSTGRES_MINOR 3 +#define POSTGRES_MICRO 2 +#define POSTGRESQL_VERSION MY_STRINGIFY(POSTGRESQL_MAJOR) "." \ + MY_STRINGIFY(POSTGRESQL_MINOR) "." \ + MY_STRINGIFY(POSTGRESQL_MICRO) + + +struct MutexHolder { osl::Mutex m_mutex; }; +// use this to switch off sdbc support ! +// typedef cppu::WeakComponentImplHelper2< +// com::sun::star::sdbc::XDriver, +// com::sun::star::lang::XServiceInfo +// > DriverBase ; +typedef cppu::WeakComponentImplHelper3< + com::sun::star::sdbc::XDriver, + com::sun::star::lang::XServiceInfo, + com::sun::star::sdbcx::XDataDefinitionSupplier > DriverBase ; +class Driver : public MutexHolder, public DriverBase +{ + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_ctx; + com::sun::star::uno::Reference< com::sun::star::lang::XMultiComponentFactory > m_smgr; + +public: + Driver ( const com::sun::star::uno::Reference < com::sun::star::uno::XComponentContext > & ctx ) + : DriverBase( this->m_mutex ), + m_ctx( ctx ), + m_smgr( ctx->getServiceManager() ) + {} + +public: // XDriver + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connect( + const ::rtl::OUString& url, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL acceptsURL( const ::rtl::OUString& url ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sdbc::DriverPropertyInfo > SAL_CALL getPropertyInfo( + const ::rtl::OUString& url, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getMajorVersion( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getMinorVersion( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XServiceInfo + // XServiceInfo + virtual rtl::OUString SAL_CALL getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService(const rtl::OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException); + +public: // XDataDefinitionSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL + getDataDefinitionByConnection( + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& connection ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL + getDataDefinitionByURL( + const ::rtl::OUString& url, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL disposing(); + +}; + + +} + +#endif diff --git connectivity/source/drivers/postgresql/pq_fakedupdateableresultset.cxx connectivity/source/drivers/postgresql/pq_fakedupdateableresultset.cxx new file mode 100644 index 0000000..898e9e2 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_fakedupdateableresultset.cxx @@ -0,0 +1,206 @@ +#include "pq_fakedupdateableresultset.hxx" +#include +#include + +using osl::MutexGuard; + +using rtl::OUString; + +using com::sun::star::uno::Reference; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Any; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::sdbc::SQLException; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XResultSetUpdate; +using com::sun::star::sdbc::XRowUpdate; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XStatement; + +namespace pq_sdbc_driver +{ + +FakedUpdateableResultSet::FakedUpdateableResultSet( + const ::rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner, + ConnectionSettings **pSettings, + PGresult *result, + const rtl::OUString &schema, + const rtl::OUString &table, + const rtl::OUString &aReason ) + : ResultSet( mutex, owner, pSettings, result, schema, table ), + m_aReason( aReason ) +{} + + +com::sun::star::uno::Any FakedUpdateableResultSet::queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException) +{ + Any ret = ResultSet::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< XResultSetUpdate * > ( this ), + static_cast< XRowUpdate * > ( this ) ); + return ret; +} + + +com::sun::star::uno::Sequence< com::sun::star::uno::Type > FakedUpdateableResultSet::getTypes() + throw( com::sun::star::uno::RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< XResultSetUpdate> *) 0 ), + getCppuType( (Reference< XRowUpdate> *) 0 ), + ResultSet::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); + +} + +com::sun::star::uno::Sequence< sal_Int8> FakedUpdateableResultSet::getImplementationId() + throw( com::sun::star::uno::RuntimeException ) +{ + static cppu::OImplementationId *pId; + if( ! pId ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( ! pId ) + { + static cppu::OImplementationId id(sal_False); + pId = &id; + } + } + return pId->getImplementationId(); +} + +void FakedUpdateableResultSet::insertRow( ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateRow( ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::deleteRow( ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); + } + +void FakedUpdateableResultSet::cancelRowUpdates( ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::moveToInsertRow( ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::moveToCurrentRow( ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + + +void FakedUpdateableResultSet::updateNull( sal_Int32 columnIndex ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateFloat( sal_Int32 columnIndex, float x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateBytes( sal_Int32 columnIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateBinaryStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateCharacterStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +void FakedUpdateableResultSet::updateNumericObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x, sal_Int32 scale ) throw (SQLException, RuntimeException) +{ + throw SQLException( m_aReason, *this, OUString(),1,Any() ); +} + +} diff --git connectivity/source/drivers/postgresql/pq_fakedupdateableresultset.hxx connectivity/source/drivers/postgresql/pq_fakedupdateableresultset.hxx new file mode 100644 index 0000000..6eb387b --- /dev/null +++ connectivity/source/drivers/postgresql/pq_fakedupdateableresultset.hxx @@ -0,0 +1,133 @@ +/************************************************************************* + * + * $RCSfile: pq_fakedupdateableresultset.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/05/09 19:47:14 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#ifndef PG_UPDATEABLERESULTSET_HXX_ +#define PG_UPDATEABLERESULTSET_HXX_ + +#include +#include + +#include "pq_resultset.hxx" + +namespace pq_sdbc_driver +{ +/** necessary to avoid crashes in OOo, when an updateable result set is requested, + but cannot be delivered. + */ +class FakedUpdateableResultSet : + public ResultSet, + public com::sun::star::sdbc::XResultSetUpdate, + public com::sun::star::sdbc::XRowUpdate +{ + ::rtl::OUString m_aReason; + +public: + FakedUpdateableResultSet( + const ::rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner, + ConnectionSettings **pSettings, + PGresult *result, + const rtl::OUString &schema, + const rtl::OUString &table, + const rtl::OUString &aReason ); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { ResultSet::acquire(); } + virtual void SAL_CALL release() throw() { ResultSet::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XTypeProvider + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XResultSetUpdate + virtual void SAL_CALL insertRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deleteRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL cancelRowUpdates( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL moveToInsertRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL moveToCurrentRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XRowUpdate + virtual void SAL_CALL updateNull( sal_Int32 columnIndex ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateFloat( sal_Int32 columnIndex, float x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateDouble( sal_Int32 columnIndex, double x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateBytes( sal_Int32 columnIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateBinaryStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateCharacterStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateNumericObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x, sal_Int32 scale ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +}; +} +#endif diff --git connectivity/source/drivers/postgresql/pq_preparedstatement.cxx connectivity/source/drivers/postgresql/pq_preparedstatement.cxx new file mode 100644 index 0000000..1d66a8a --- /dev/null +++ connectivity/source/drivers/postgresql/pq_preparedstatement.cxx @@ -0,0 +1,881 @@ +/************************************************************************* + * + * $RCSfile: pq_preparedstatement.cxx,v $ + * + * $Revision: 1.1.2.10 $ + * + * last change: $Author: jbu $ $Date: 2008/07/07 21:37:11 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include "pq_preparedstatement.hxx" +#include "pq_resultset.hxx" +#include "pq_tools.hxx" +#include "pq_statics.hxx" +#include "pq_statement.hxx" + +#include +#include + + +#include +#include + +#include + +#include +#include + +using osl::Mutex; +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringToOString; +using rtl::OStringToOUString; +using rtl::OUStringBuffer; +using rtl::OStringBuffer; +using rtl::OString; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Exception; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::UNO_QUERY; + +using com::sun::star::lang::IllegalArgumentException; + +using com::sun::star::sdbc::XWarningsSupplier; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XRef; +using com::sun::star::sdbc::XBlob; +using com::sun::star::sdbc::XClob; +using com::sun::star::sdbc::XArray; +using com::sun::star::sdbc::XConnection; +using com::sun::star::sdbc::XGeneratedResultSet; +using com::sun::star::sdbc::SQLException; + +using com::sun::star::beans::Property; +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::XMultiPropertySet; +using com::sun::star::beans::XFastPropertySet; + +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) +namespace pq_sdbc_driver +{ +static ::cppu::IPropertyArrayHelper & getPreparedStatementPropertyArrayHelper() +{ + static ::cppu::IPropertyArrayHelper *pArrayHelper; + if( ! pArrayHelper ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pArrayHelper ) + { + static Property aTable[] = + { + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("CursorName") ), 0, + ::getCppuType( (OUString *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("EscapeProcessing") ), 1, + ::getBooleanCppuType() , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("FetchDirection") ), 2, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("FetchSize") ), 3, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("MaxFieldSize") ), 4, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("MaxRows") ), 5, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("QueryTimeOut") ), 6, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetConcurrency") ), 7, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetType") ), 8, + ::getCppuType( (sal_Int32 *)0) , 0 ) + }; + OSL_ASSERT( sizeof(aTable)/ sizeof(Property) == PREPARED_STATEMENT_SIZE ); + static ::cppu::OPropertyArrayHelper arrayHelper( aTable, PREPARED_STATEMENT_SIZE, sal_True ); + pArrayHelper = &arrayHelper; + } + } + return *pArrayHelper; +} + +static bool isOperator( char c ) +{ + static const char * operators = "<>=()!/&%.,;"; + + const char * w = operators; + for( ; *w && *w != c ; w ++); + return *w != 0; +} + +static bool isNamedParameterStart( const rtl::OString & o , int index ) +{ + return o[index] == ':' && ( + isWhitespace( o[index-1] ) || isOperator(o[index-1]) ); +} + +static bool isQuoted( const rtl::OString & str ) +{ + return str[0] == '"' || str[0] == '\''; +} + +PreparedStatement::PreparedStatement( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< XConnection > & conn, + struct ConnectionSettings *pSettings, + const ::rtl::OString & stmt ) + : OComponentHelper( refMutex->mutex ), + OPropertySetHelper( OComponentHelper::rBHelper ), + m_refMutex( refMutex ), + m_connection( conn ), + m_pSettings( pSettings ), + m_stmt( stmt ), + m_lastOidInserted( InvalidOid ) +{ + m_props[PREPARED_STATEMENT_QUERY_TIME_OUT] = makeAny( (sal_Int32)0 ); + m_props[PREPARED_STATEMENT_MAX_ROWS] = makeAny( (sal_Int32)0 ); + m_props[PREPARED_STATEMENT_RESULT_SET_CONCURRENCY] = makeAny( + com::sun::star::sdbc::ResultSetConcurrency::READ_ONLY ); + m_props[PREPARED_STATEMENT_RESULT_SET_TYPE] = makeAny( + com::sun::star::sdbc::ResultSetType::SCROLL_INSENSITIVE ); + + splitSQL( m_stmt, m_splittedStatement ); + int elements = 0; + for( int i = 0, max = m_splittedStatement.size(); i < max ; i ++ ) + { + const OString &str = m_splittedStatement[i]; + // ignore quoted strings .... + if( ! isQuoted( str ) ) + { + // the ':' cannot be the first or the last part of the + // token, + // the ? cannot be the first part of the token , so we start + // at one + for( int index = 1 ; index < str.getLength() ; index ++ ) + { + if( str[index] == '?' || + isNamedParameterStart( str , index ) + ) + { + elements ++; + } + } + } + } + m_vars = OStringVector ( elements ); +} + +PreparedStatement::~PreparedStatement() +{ + POSTGRE_TRACE( "dtor PreparedStatement" ); +} + +void PreparedStatement::checkColumnIndex( sal_Int32 parameterIndex ) +{ + if( parameterIndex < 1 || parameterIndex > (sal_Int32) m_vars.size() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "pq_preparedstatement: parameter index out of range (expected 1 to " ); + buf.append( (sal_Int32 ) m_vars.size() ); + buf.appendAscii( ", got " ); + buf.append( parameterIndex ); + buf.appendAscii( ", statement '" ); + buf.append( OStringToOUString( m_stmt, m_pSettings->encoding ) ); + buf.appendAscii( "')" ); + throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any () ); + } +} +void PreparedStatement::checkClosed() throw (SQLException, RuntimeException ) +{ + if( ! m_pSettings || ! m_pSettings->pConnection ) + throw SQLException( + ASCII_STR("pq_driver: PreparedStatement or connection has already been closed !" ), + *this, OUString(),1,Any()); +} + +Any PreparedStatement::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = OComponentHelper::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( reqType, + static_cast< XWarningsSupplier * > ( this ), + static_cast< XPreparedStatement * > ( this ), + static_cast< com::sun::star::sdbc::XResultSetMetaDataSupplier * > ( this ), + static_cast< XParameters * > ( this ), + static_cast< XCloseable * > ( this ), + static_cast< XGeneratedResultSet * > ( this ), + static_cast< XPropertySet * > ( this ), + static_cast< XMultiPropertySet * > ( this ), + static_cast< XFastPropertySet * > ( this ) ); + return ret; +} + + +Sequence< Type > PreparedStatement::getTypes() throw ( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< XWarningsSupplier> *) 0 ), + getCppuType( (Reference< XPreparedStatement> *) 0 ), + getCppuType( (Reference< com::sun::star::sdbc::XResultSetMetaDataSupplier> *) 0 ), + getCppuType( (Reference< XParameters> *) 0 ), + getCppuType( (Reference< XCloseable> *) 0 ), + getCppuType( (Reference< XGeneratedResultSet> *) 0 ), + getCppuType( (Reference< XPropertySet >*) 0 ), + getCppuType( (Reference< XFastPropertySet > *) 0 ), + getCppuType( (Reference< XMultiPropertySet > *) 0 ), + OComponentHelper::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> PreparedStatement::getImplementationId() throw ( RuntimeException ) +{ + static cppu::OImplementationId *pId; + if( ! pId ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( ! pId ) + { + static cppu::OImplementationId id(sal_False); + pId = &id; + } + } + return pId->getImplementationId(); +} + +void PreparedStatement::close( ) throw (SQLException, RuntimeException) +{ + // let the connection die without acquired mutex ! + Reference< XConnection > r; + Reference< XCloseable > resultSet; + { + MutexGuard guard( m_refMutex->mutex ); + m_pSettings = 0; + r = m_connection; + m_connection.clear(); + + resultSet = m_lastResultset; + m_lastResultset.clear(); + } + if( resultSet.is() ) + { + resultSet->close(); + } +} + +void PreparedStatement::raiseSQLException( + const char * errorMsg, const char *errorType ) + throw( SQLException ) +{ + OUStringBuffer buf(128); + buf.appendAscii( "pq_driver: "); + if( errorType ) + { + buf.appendAscii( "[" ); + buf.appendAscii( errorType ); + buf.appendAscii( "]" ); + } + buf.append( + rtl::OUString( errorMsg, strlen(errorMsg) , m_pSettings->encoding ) ); + buf.appendAscii( " (caused by statement '" ); + buf.appendAscii( m_executedStatement ); + buf.appendAscii( "')" ); + OUString error = buf.makeStringAndClear(); + log( m_pSettings, LogLevel::ERROR, error ); + throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any() ); +} + +Reference< XResultSet > PreparedStatement::executeQuery( ) + throw (SQLException, RuntimeException) +{ + Reference< XCloseable > lastResultSet = m_lastResultset; + if( lastResultSet.is() ) + lastResultSet->close(); + + if( ! execute( ) ) + { + raiseSQLException( "not a query" ); + } + return Reference< XResultSet > ( m_lastResultset, com::sun::star::uno::UNO_QUERY ); +} + +sal_Int32 PreparedStatement::executeUpdate( ) + throw (SQLException, RuntimeException) +{ + if( execute( ) ) + { + raiseSQLException( "not a command" ); + } + return m_multipleResultUpdateCount; +} + +sal_Bool PreparedStatement::execute( ) + throw (SQLException, RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + + OStringBuffer buf( m_stmt.getLength() *2 ); + + int vars = 0; + for( int i = 0 ; i < m_splittedStatement.size() ; i ++ ) + { + const OString &str = m_splittedStatement[i]; +// printf( "Splitted %d %s\n" , i , str.getStr() ); + if( isQuoted( str ) ) + { + buf.append( str ); + } + else + { + int start = 0,index; + for( index = 1 ; index < str.getLength() ; index ++ ) + { + if( str[index] == '?' ) + { + buf.append( str.getStr()+start, index - start ); + buf.append( m_vars[vars] ); + vars ++; + start =index+1; + } + else + { + if ( isNamedParameterStart( str, index ) ) + { + buf.append( str.getStr()+start, index -start ); + buf.append( m_vars[vars] ); + + // skip to the end of the named parameter + for( ; index < str.getLength() && + ! ( isWhitespace( str[index] ) || isOperator( str[index] ) ) ; index ++ ); + start = index; + vars ++; + } + } + } +// if( index +1 >= str.getLength() ) +// { + buf.append( str.getStr() + start, index -start ); +// } + } + } + + m_executedStatement = buf.makeStringAndClear(); + + m_lastResultset.clear(); + m_lastTableInserted = rtl::OUString(); + + struct CommandData data; + data.refMutex = m_refMutex; + data.ppSettings = &m_pSettings; + data.pLastOidInserted = &m_lastOidInserted; + data.pLastQuery = &m_lastQuery; + data.pMultipleResultUpdateCount = &m_multipleResultUpdateCount; + data.pMultipleResultAvailable = &m_multipleResultAvailable; + data.pLastTableInserted = &m_lastTableInserted; + data.pLastResultset = &m_lastResultset; + data.owner = *this; + data.tableSupplier = Reference< com::sun::star::sdbcx::XTablesSupplier >( m_connection, UNO_QUERY ); + data.concurrency = extractIntProperty( this, getStatics().RESULT_SET_CONCURRENCY ); + + return executePostgresCommand( m_executedStatement , &data ); // see pq_statement.cxx +} + +Reference< XConnection > PreparedStatement::getConnection( ) + throw (SQLException, RuntimeException) +{ + Reference< XConnection > ret; + { + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + ret = m_connection; + } + return ret; +} + + +void PreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 sqlType ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( parameterIndex ); + m_vars[parameterIndex-1] = OString( "NULL" ); +} + +void PreparedStatement::setObjectNull( + sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( parameterIndex ); + m_vars[parameterIndex-1] = OString( "NULL" ); +} + + +void PreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard(m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( parameterIndex ); + if( x ) + m_vars[parameterIndex-1] = OString( "'t'" ); + else + m_vars[parameterIndex-1] = OString( "'f'" ); +} + +void PreparedStatement::setByte( sal_Int32 parameterIndex, sal_Int8 x ) + throw (SQLException, RuntimeException) +{ + setInt(parameterIndex,x); +} + +void PreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 x ) + throw (SQLException, RuntimeException) +{ + setInt(parameterIndex, x ); +} + +void PreparedStatement::setInt( sal_Int32 parameterIndex, sal_Int32 x ) + throw (SQLException, RuntimeException) +{ +// printf( "setString %d %d\n ", parameterIndex, x); + MutexGuard guard(m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( parameterIndex ); + OStringBuffer buf( 20 ); + buf.append( "'" ); + buf.append( (sal_Int32) x ); + buf.append( "'" ); + m_vars[parameterIndex-1] = buf.makeStringAndClear(); +} + +void PreparedStatement::setLong( sal_Int32 parameterIndex, sal_Int64 x ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard(m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( parameterIndex ); + OStringBuffer buf( 20 ); + buf.append( "'" ); + buf.append( (sal_Int64) x ); + buf.append( "'" ); + m_vars[parameterIndex-1] = buf.makeStringAndClear(); +} + +void PreparedStatement::setFloat( sal_Int32 parameterIndex, float x ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard(m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( parameterIndex ); + OStringBuffer buf( 20 ); + buf.append( "'" ); + buf.append( x ); + buf.append( "'" ); + m_vars[parameterIndex-1] = buf.makeStringAndClear(); +} + +void PreparedStatement::setDouble( sal_Int32 parameterIndex, double x ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard(m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( parameterIndex ); + OStringBuffer buf( 20 ); + buf.append( "'" ); + buf.append( x ); + buf.append( "'" ); + m_vars[parameterIndex-1] = buf.makeStringAndClear(); +} + +void PreparedStatement::setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) + throw (SQLException, RuntimeException) +{ +// printf( "setString %d %s\n ", parameterIndex, +// OUStringToOString( x , RTL_TEXTENCODING_ASCII_US ).getStr()); + MutexGuard guard(m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( parameterIndex ); + OStringBuffer buf( 20 ); + buf.append( "'" ); + OString y = OUStringToOString( x, m_pSettings->encoding ); + buf.ensureCapacity( y.getLength() * 2 + 2 ); + int len = PQescapeString( ((char*)buf.getStr())+1, y.getStr() , y.getLength() ); + buf.setLength( 1 + len ); + buf.append( "'" ); + m_vars[parameterIndex-1] = buf.makeStringAndClear(); +} + +void PreparedStatement::setBytes( + sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard(m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( parameterIndex ); + OStringBuffer buf( 20 ); + buf.append( "'" ); + size_t len; + unsigned char * escapedString = + PQescapeBytea( (unsigned char *)x.getConstArray(), x.getLength(), &len); + if( ! escapedString ) + { + throw SQLException( + ASCII_STR("pq_preparedstatement.setBytes: Error during converting bytesequence to an SQL conform string" ), + *this, OUString(), 1, Any() ); + } + buf.append( (const sal_Char *)escapedString, len -1 ); + free( escapedString ); + buf.append( "'" ); + m_vars[parameterIndex-1] = buf.makeStringAndClear(); +} + + +void PreparedStatement::setDate( sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x ) + throw (SQLException, RuntimeException) +{ + setString( parameterIndex, date2String( x ) ); +} + +void PreparedStatement::setTime( sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x ) + throw (SQLException, RuntimeException) +{ + setString( parameterIndex, time2String( x ) ); +} + +void PreparedStatement::setTimestamp( + sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x ) + throw (SQLException, RuntimeException) +{ + setString( parameterIndex, dateTime2String( x ) ); +} + +void PreparedStatement::setBinaryStream( + sal_Int32 parameterIndex, + const Reference< ::com::sun::star::io::XInputStream >& x, + sal_Int32 length ) + throw (SQLException, RuntimeException) +{ + throw SQLException( + ASCII_STR( "pq_preparedstatement: setBinaryStream not implemented" ), + *this, OUString(), 1, Any () ); +} + +void PreparedStatement::setCharacterStream( + sal_Int32 parameterIndex, + const Reference< ::com::sun::star::io::XInputStream >& x, + sal_Int32 length ) + throw (SQLException, RuntimeException) +{ + throw SQLException( + ASCII_STR( "pq_preparedstatement: setCharacterStream not implemented" ), + *this, OUString(), 1, Any () ); +} + +void PreparedStatement::setObject( sal_Int32 parameterIndex, const Any& x ) + throw (SQLException, RuntimeException) +{ + if( ! implSetObject( this, parameterIndex, x )) + { + OUStringBuffer buf; + buf.append( ASCII_STR("pq_preparedstatement::setObject: can't convert value of type " ) ); + buf.append( x.getValueTypeName() ); + throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any () ); + } +} + +void PreparedStatement::setObjectWithInfo( + sal_Int32 parameterIndex, + const Any& x, + sal_Int32 targetSqlType, + sal_Int32 scale ) + throw (SQLException, RuntimeException) +{ + if( com::sun::star::sdbc::DataType::DECIMAL == targetSqlType || + com::sun::star::sdbc::DataType::NUMERIC == targetSqlType ) + { + double myDouble; + OUString myString; + if( x >>= myDouble ) + { + myString = OUString::valueOf( myDouble ); + } + else + { + x >>= myString; + } + if( myString.getLength() ) + { +// printf( "setObjectWithInfo %s\n", OUStringToOString(myString,RTL_TEXTENCODING_ASCII_US).getStr()); + setString( parameterIndex, myString ); + } + else + { + OUStringBuffer buf; + buf.append( ASCII_STR("pq_preparedstatement::setObjectWithInfo: can't convert value of type " ) ); + buf.append( x.getValueTypeName() ); + buf.append( ASCII_STR(" to type DECIMAL or NUMERIC" ) ); + throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any () ); + } + } + else + { + setObject( parameterIndex, x ); + } + +} + +void PreparedStatement::setRef( + sal_Int32 parameterIndex, + const Reference< XRef >& x ) + throw (SQLException, RuntimeException) +{ + throw SQLException( + ASCII_STR( "pq_preparedstatement: setRef not implemented" ), + *this, OUString(), 1, Any () ); + +} + +void PreparedStatement::setBlob( + sal_Int32 parameterIndex, + const Reference< XBlob >& x ) + throw (SQLException, RuntimeException) +{ + throw SQLException( + ASCII_STR( "pq_preparedstatement: setBlob not implemented" ), + *this, OUString(), 1, Any () ); +} + +void PreparedStatement::setClob( + sal_Int32 parameterIndex, + const Reference< XClob >& x ) + throw (SQLException, RuntimeException) +{ + throw SQLException( + ASCII_STR( "pq_preparedstatement: setClob not implemented" ), + *this, OUString(), 1, Any () ); +} + +void PreparedStatement::setArray( + sal_Int32 parameterIndex, + const Reference< XArray >& x ) + throw (SQLException, RuntimeException) +{ + setString( parameterIndex, array2String( x->getArray( 0 ) ) ); + +// throw SQLException( +// ASCII_STR( "pq_preparedstatement: setArray not implemented" ), +// *this, OUString(), 1, Any () ); +} + +void PreparedStatement::clearParameters( ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard(m_refMutex->mutex ); + m_vars = OStringVector ( m_vars.size() ); +} + +Any PreparedStatement::getWarnings( ) + throw (SQLException,RuntimeException) +{ + return Any(); +} + +void PreparedStatement::clearWarnings( ) + throw (SQLException, RuntimeException) +{ +} + +Reference< ::com::sun::star::sdbc::XResultSetMetaData > PreparedStatement::getMetaData() + throw (SQLException,RuntimeException) +{ + Reference< com::sun::star::sdbc::XResultSetMetaData > ret; + Reference< com::sun::star::sdbc::XResultSetMetaDataSupplier > supplier( m_lastResultset, UNO_QUERY ); + if( supplier.is() ) + ret = supplier->getMetaData(); + return ret; +} + +::cppu::IPropertyArrayHelper & PreparedStatement::getInfoHelper() +{ + return getPreparedStatementPropertyArrayHelper(); +} + + +sal_Bool PreparedStatement::convertFastPropertyValue( + Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) + throw (IllegalArgumentException) +{ + sal_Bool bRet; + rOldValue = m_props[nHandle]; + switch( nHandle ) + { + case PREPARED_STATEMENT_CURSOR_NAME: + { + OUString val; + bRet = ( rValue >>= val ); + rConvertedValue = makeAny( val ); + break; + } + case PREPARED_STATEMENT_ESCAPE_PROCESSING: + { + sal_Bool val; + bRet = ( rValue >>= val ); + rConvertedValue = makeAny( val ); + break; + } + case PREPARED_STATEMENT_FETCH_DIRECTION: + case PREPARED_STATEMENT_FETCH_SIZE: + case PREPARED_STATEMENT_MAX_FIELD_SIZE: + case PREPARED_STATEMENT_MAX_ROWS: + case PREPARED_STATEMENT_QUERY_TIME_OUT: + case PREPARED_STATEMENT_RESULT_SET_CONCURRENCY: + case PREPARED_STATEMENT_RESULT_SET_TYPE: + { + sal_Int32 val; + bRet = ( rValue >>= val ); + rConvertedValue = makeAny( val ); + break; + } + default: + { + OUStringBuffer buf(128); + buf.appendAscii( "pq_statement: Invalid property handle (" ); + buf.append( nHandle ); + buf.appendAscii( ")" ); + throw IllegalArgumentException( buf.makeStringAndClear(), *this, 2 ); + } + } + return bRet; +} + + +void PreparedStatement::setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle,const Any& rValue ) throw (Exception) +{ + m_props[nHandle] = rValue; +} + +void PreparedStatement::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const +{ + rValue = m_props[nHandle]; +} + +Reference < XPropertySetInfo > PreparedStatement::getPropertySetInfo() + throw(RuntimeException) +{ + return OPropertySetHelper::createPropertySetInfo( getPreparedStatementPropertyArrayHelper() ); +} + +void PreparedStatement::disposing() +{ + close(); +} + + +Reference< XResultSet > PreparedStatement::getResultSet( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return Reference< XResultSet > ( m_lastResultset, com::sun::star::uno::UNO_QUERY ); +} +sal_Int32 PreparedStatement::getUpdateCount( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return m_multipleResultUpdateCount; +} +sal_Bool PreparedStatement::getMoreResults( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +Reference< XResultSet > PreparedStatement::getGeneratedValues( ) + throw (SQLException, RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + return getGeneratedValuesFromLastInsert( + m_pSettings, m_connection, m_lastOidInserted, m_lastTableInserted, m_lastQuery ); +} + + +} diff --git connectivity/source/drivers/postgresql/pq_preparedstatement.hxx connectivity/source/drivers/postgresql/pq_preparedstatement.hxx new file mode 100644 index 0000000..55f2a6f --- /dev/null +++ connectivity/source/drivers/postgresql/pq_preparedstatement.hxx @@ -0,0 +1,284 @@ +/************************************************************************* + * + * $RCSfile: pq_preparedstatement.hxx,v $ + * + * $Revision: 1.1.2.5 $ + * + * last change: $Author: jbu $ $Date: 2006/01/22 15:14:29 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_PREPARED_STATEMENT_HXX_ +#define _PQ_PREPARED_STATEMENT_HXX_ +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include "pq_connection.hxx" +namespace rtl { class OString; } +namespace pq_sdbc_driver +{ + +static const sal_Int32 PREPARED_STATEMENT_CURSOR_NAME = 0; +static const sal_Int32 PREPARED_STATEMENT_ESCAPE_PROCESSING = 1; +static const sal_Int32 PREPARED_STATEMENT_FETCH_DIRECTION = 2; +static const sal_Int32 PREPARED_STATEMENT_FETCH_SIZE = 3; +static const sal_Int32 PREPARED_STATEMENT_MAX_FIELD_SIZE = 4; +static const sal_Int32 PREPARED_STATEMENT_MAX_ROWS = 5; +static const sal_Int32 PREPARED_STATEMENT_QUERY_TIME_OUT = 6; +static const sal_Int32 PREPARED_STATEMENT_RESULT_SET_CONCURRENCY = 7; +static const sal_Int32 PREPARED_STATEMENT_RESULT_SET_TYPE = 8; + +#define PREPARED_STATEMENT_SIZE 9 +class ResultSet; + +class PreparedStatement : public cppu::OComponentHelper, + public cppu::OPropertySetHelper, + public com::sun::star::sdbc::XPreparedStatement, + public com::sun::star::sdbc::XParameters, + public com::sun::star::sdbc::XCloseable, + public com::sun::star::sdbc::XWarningsSupplier, + public com::sun::star::sdbc::XMultipleResults, + public com::sun::star::sdbc::XGeneratedResultSet, + public com::sun::star::sdbc::XResultSetMetaDataSupplier +{ +private: + com::sun::star::uno::Any m_props[PREPARED_STATEMENT_SIZE]; + com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > m_connection; + ConnectionSettings *m_pSettings; + ::com::sun::star::uno::Reference< com::sun::star::sdbc::XCloseable > m_lastResultset; + ::rtl::OString m_stmt; + ::rtl::OString m_executedStatement; + ::rtl::Reference< RefCountedMutex > m_refMutex; + OStringVector m_vars; + OStringVector m_splittedStatement; + sal_Bool m_multipleResultAvailable; + sal_Int32 m_multipleResultUpdateCount; + sal_Int32 m_lastOidInserted; + rtl::OUString m_lastTableInserted; + rtl::OString m_lastQuery; + +public: + /** + * @param ppConnection The piece of memory, pConnection points to, is accessisble + * as long as a reference to paramenter con is held. + */ + PreparedStatement( const rtl::Reference< RefCountedMutex > & refMutex, + const com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection> & con, + struct ConnectionSettings *pSettings, + const rtl::OString &stmt ); + + virtual ~PreparedStatement(); +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XCloseable + virtual void SAL_CALL close( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XPreparedStatement + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL executeQuery() + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL executeUpdate( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL execute( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL getConnection( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); +public: // XParameters + virtual void SAL_CALL setNull( sal_Int32 parameterIndex, sal_Int32 sqlType ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setObjectNull( + sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setBoolean( sal_Int32 parameterIndex, sal_Bool x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setByte( sal_Int32 parameterIndex, sal_Int8 x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setShort( sal_Int32 parameterIndex, sal_Int16 x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setInt( sal_Int32 parameterIndex, sal_Int32 x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setLong( sal_Int32 parameterIndex, sal_Int64 x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setFloat( sal_Int32 parameterIndex, float x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDouble( sal_Int32 parameterIndex, double x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setBytes( + sal_Int32 parameterIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDate( sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setTime( sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setTimestamp( + sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setBinaryStream( + sal_Int32 parameterIndex, + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, + sal_Int32 length ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setCharacterStream( + sal_Int32 parameterIndex, + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, + sal_Int32 length ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setObject( sal_Int32 parameterIndex, const ::com::sun::star::uno::Any& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setObjectWithInfo( + sal_Int32 parameterIndex, + const ::com::sun::star::uno::Any& x, + sal_Int32 targetSqlType, + sal_Int32 scale ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setRef( + sal_Int32 parameterIndex, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef >& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setBlob( + sal_Int32 parameterIndex, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob >& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setClob( + sal_Int32 parameterIndex, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob >& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setArray( + sal_Int32 parameterIndex, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray >& x ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearParameters( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XWarningsSupplier + virtual ::com::sun::star::uno::Any SAL_CALL getWarnings( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearWarnings( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // OPropertySetHelper + virtual cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper(); + + virtual sal_Bool SAL_CALL convertFastPropertyValue( + ::com::sun::star::uno::Any & rConvertedValue, + ::com::sun::star::uno::Any & rOldValue, + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::lang::IllegalArgumentException); + + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::uno::Exception); + + virtual void SAL_CALL getFastPropertyValue( + ::com::sun::star::uno::Any& rValue, + sal_Int32 nHandle ) const; + + // XPropertySet + ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw(com::sun::star::uno::RuntimeException); + +public: // XGeneratedResultSet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL + getGeneratedValues( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XMultipleResults + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getResultSet( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getUpdateCount( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL getMoreResults( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XResultSetMetaDataSupplier (is required by framework (see + // dbaccess/source/core/api/preparedstatement.cxx::getMetaData() ) + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL getMetaData( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // OComponentHelper + virtual void SAL_CALL disposing(); + +private: + void checkColumnIndex( sal_Int32 parameterIndex ); + void checkClosed() throw (com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException); + void raiseSQLException( const char * errorMsg, const char *errorType = 0 ) + throw ( com::sun::star::sdbc::SQLException ); +// PGresult *pgExecute( ::rtl::OString *pQuery ); +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_resultset.cxx connectivity/source/drivers/postgresql/pq_resultset.cxx new file mode 100644 index 0000000..07db701 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_resultset.cxx @@ -0,0 +1,257 @@ +#include "pq_resultset.hxx" +#include "pq_resultsetmetadata.hxx" + +#include +#include + +using rtl::OUString; +using rtl::OUStringToOString; + +using osl::MutexGuard; + +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; + +using com::sun::star::sdbc::SQLException; +using com::sun::star::sdbc::XResultSetMetaData; + + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +void ResultSet::checkClosed() + throw ( com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException ) +{ + if( ! m_result ) + { + throw SQLException( ASCII_STR( "pq_resultset: already closed" ), + *this, OUString(), 1, Any() ); + } + + if( ! m_ppSettings || ! *m_ppSettings || ! (*m_ppSettings)->pConnection ) + { + throw SQLException( ASCII_STR( "pq_resultset: statement has been closed already" ), + *this, OUString(), 1, Any() ); + } + +} + +ResultSet::ResultSet( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< XInterface > & owner, + ConnectionSettings **ppSettings, + PGresult * result, + const rtl::OUString &schema, + const rtl::OUString &table) + : BaseResultSet( + refMutex, owner, PQntuples( result ), + PQnfields( result ),(*ppSettings)->tc ), + m_ppSettings( ppSettings ), + m_result( result ), + m_schema( schema ), + m_table( table ) +{ + sal_Bool b = sal_True; +// m_props[RESULTSET_IS_BOOKMARKABLE] = Any( &b, getBooleanCppuType() ); + m_props[ BASERESULTSET_RESULT_SET_TYPE] = makeAny( + com::sun::star::sdbc::ResultSetType::SCROLL_INSENSITIVE ); +} + + +Any ResultSet::getValue( sal_Int32 columnIndex ) +{ + Any ret; + if( PQgetisnull( m_result, m_row, columnIndex -1 ) ) + { + m_wasNull = true; + } + else + { + m_wasNull = false; + ret <<= ::rtl::OUString( + PQgetvalue( m_result, m_row , columnIndex -1 ) , + PQgetlength( m_result, m_row , columnIndex -1 ) , + (*m_ppSettings)->encoding ); + + } + return ret; +} + +ResultSet::~ResultSet() +{} + +void ResultSet::close( ) throw (SQLException, RuntimeException) +{ + Reference< XInterface > owner; + { + MutexGuard guard( m_refMutex->mutex ); + if( m_result ) + { + PQclear(m_result ); + m_result = 0; + m_row = -1; + } + owner = m_owner; + m_owner.clear(); + } +} + +Reference< XResultSetMetaData > ResultSet::getMetaData( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return new ResultSetMetaData( + m_refMutex, this, this, m_ppSettings, m_result, m_schema, m_table ); +} + +sal_Int32 ResultSet::findColumn( const ::rtl::OUString& columnName ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + return PQfnumber( + m_result, + OUStringToOString( columnName, (*m_ppSettings)->encoding ).getStr()) + +1; +} + +static bool isNumber( const char * data, sal_Int32 len ) +{ + bool ret = false; + if( len ) + { + ret = true; + for( int i = 0 ; i < len ; i ++ ) + { + if( ( data[i] >= '0' && data[i] <= '9' ) || + data[i] == '-' || data[i] == '+' || data[i] == '.' || data[i] == ',' ) + { + if( data[i] == '-' && i != 0 && i != len-1 ) + { + // no number, maybe a date + ret = false; + break; + } + } + else + { + ret = false; + break; + } + } + } + return ret; +} + +static bool isInteger( const char * data, sal_Int32 len ) +{ + bool ret = false; + if( len ) + { + ret = true; + for( int i = 0 ; i < len ; i ++ ) + { + if( ( data[i] >= '0' && data[i] <= '9' ) || + data[i] == '-' || data[i] == '+' ) + { + if( data[i] == '-' && i != 0 && i != len-1 ) + { + // no number, maybe a date + ret = false; + break; + } + } + else + { + ret = false; + break; + } + } + } + return ret; +} + +static bool isDate( const char * data, sal_Int32 len ) +{ + bool ret = false; + return 10 == len && + '-' == data[4] && + '-' == data[7] && + isInteger( &(data[0]),4 ) && + isInteger( &(data[5]),2) && + isInteger( &(data[8]),2 ); +} + +static bool isTime( const char * data, sal_Int32 len ) +{ + bool ret = false; + return 8 == len && + ':' == data[2] && + ':' == data[5] && + isInteger( &(data[0]),2 ) && + isInteger( &(data[3]),2) && + isInteger( &(data[6]),2 ); + +} + +static bool isTimestamp( const char * data, sal_Int32 len ) +{ + return len == 19 && isDate( data, 10) && isTime( &(data[11]),8 ); +} + +sal_Int32 ResultSet::guessDataType( sal_Int32 column ) +{ + // we don't look into more than 100 rows ... + sal_Int32 ret = com::sun::star::sdbc::DataType::INTEGER; + + int maxRows = ( m_rowCount > 100 ? 100 : m_rowCount ); + for( int i = 0 ; i < maxRows ; i ++ ) + { + if( ! PQgetisnull( m_result, i , column-1 ) ) + { + const char * p = PQgetvalue( m_result, i , column -1 ); + int len = PQgetlength( m_result, i , column -1 ); + + if( com::sun::star::sdbc::DataType::INTEGER == ret ) + { + if( ! isInteger( p,len ) ) + ret = com::sun::star::sdbc::DataType::NUMERIC; + } + if( com::sun::star::sdbc::DataType::NUMERIC == ret ) + { + if( ! isNumber( p,len ) ) + { + ret = com::sun::star::sdbc::DataType::DATE; + } + } + if( com::sun::star::sdbc::DataType::DATE == ret ) + { + if( ! isDate( p,len ) ) + { + ret = com::sun::star::sdbc::DataType::TIME; + } + } + if( com::sun::star::sdbc::DataType::TIME == ret ) + { + if( ! isTime( p,len ) ) + { + ret = com::sun::star::sdbc::DataType::TIMESTAMP; + } + } + if( com::sun::star::sdbc::DataType::TIMESTAMP == ret ) + { + if( ! isTimestamp( p,len ) ) + { + ret = com::sun::star::sdbc::DataType::LONGVARCHAR; + break; + } + } + } + } + return ret; +} + +} diff --git connectivity/source/drivers/postgresql/pq_resultset.hxx connectivity/source/drivers/postgresql/pq_resultset.hxx new file mode 100644 index 0000000..0d0e8b7 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_resultset.hxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * $RCSfile: pq_resultset.hxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2006/05/01 19:19:06 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#ifndef _PG_RESULTSET_HXX_ +#define _PG_RESULTSET_HXX_ + +#include +#include + +#include +#include +#include +#include +#include "pq_connection.hxx" +#include "pq_baseresultset.hxx" + +namespace pq_sdbc_driver +{ + +class ResultSet : public BaseResultSet +{ +protected: + PGresult *m_result; + ::rtl::OUString m_schema; + ::rtl::OUString m_table; + ConnectionSettings **m_ppSettings; + +protected: + /** mutex should be locked before called + */ + virtual void checkClosed() + throw ( com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException ); + + /** unchecked, acquire mutex before calling + */ + virtual ::com::sun::star::uno::Any getValue( sal_Int32 columnIndex ); + +public: + ResultSet( + const ::rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner, + ConnectionSettings **pSettings, + PGresult *result, + const rtl::OUString &schema, + const rtl::OUString &table ); + ~ResultSet(); + +public: // XCloseable + virtual void SAL_CALL close( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XResultSetMetaDataSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL getMetaData( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XColumnLocate + virtual sal_Int32 SAL_CALL findColumn( const ::rtl::OUString& columnName ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: + sal_Int32 guessDataType( sal_Int32 column ); +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_resultsetmetadata.cxx connectivity/source/drivers/postgresql/pq_resultsetmetadata.cxx new file mode 100644 index 0000000..d351b4c --- /dev/null +++ connectivity/source/drivers/postgresql/pq_resultsetmetadata.cxx @@ -0,0 +1,523 @@ +/************************************************************************* + * + * $RCSfile: pq_resultsetmetadata.cxx,v $ + * + * $Revision: 1.1.2.7 $ + * + * last change: $Author: jbu $ $Date: 2006/05/27 11:32:13 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#include + +#include "pq_resultsetmetadata.hxx" +#include "pq_resultset.hxx" +#include "pq_tools.hxx" +#include "pq_statics.hxx" + +#include +#include +#include + + +using osl::Mutex; +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OString; + +using com::sun::star::uno::Any; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Exception; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::UNO_QUERY; + +using com::sun::star::lang::IllegalArgumentException; + +using com::sun::star::sdbc::SQLException; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XResultSet; +// using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbcx::XColumnsSupplier; +using com::sun::star::sdbcx::XTablesSupplier; + +using com::sun::star::beans::XPropertySet; +using com::sun::star::container::XNameAccess; + + +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +namespace pq_sdbc_driver +{ + +// struct ColumnMetaData +// { +// rtl::OUString tableName; +// rtl::OUString schemaTableName; +// rtl::OUString typeName; +// com::sun::star::sdbc::DataType type; +// sal_Int32 precision; +// sal_Int32 scale; +// sal_Bool isCurrency; +// sal_Bool isNullable; +// sal_Bool isAutoIncrement; +// sal_Bool isReadOnly; +// sal_Bool isSigned; +// }; + +// is not exported by the postgres header +const static int PQ_VARHDRSZ = sizeof( sal_Int32 ); + +static void extractPrecisionAndScale( sal_Int32 atttypmod, sal_Int32 *precision, sal_Int32 *scale ) +{ + if( atttypmod < PQ_VARHDRSZ ) + { + *precision = 0; + *scale = 0; + } + else + { + if( atttypmod & 0xffff0000 ) + { + *precision = ( ( atttypmod - PQ_VARHDRSZ ) >> 16 ) & 0xffff; + *scale = (atttypmod - PQ_VARHDRSZ ) & 0xffff; + } + else + { + *precision = atttypmod - PQ_VARHDRSZ; + *scale = 0; + } + } +} + +ResultSetMetaData::ResultSetMetaData( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet > & origin, + ResultSet * pResultSet, + ConnectionSettings **ppSettings, + PGresult *pResult, + const rtl::OUString &schemaName, + const rtl::OUString &tableName ) : + m_refMutex( refMutex ), + m_origin( origin ), + m_ppSettings( ppSettings ), + m_colCount( PQnfields( pResult ) ), + m_tableName( tableName ), + m_schemaName( schemaName ), + m_checkedForTable( false ), + m_checkedForTypes( false ), + m_colDesc( PQnfields( pResult ) ), + m_pResultSet( pResultSet ) +{ + + // extract all needed information from the result object, so that we don't + // need it anymore after this call ! + for( int col = 0; col < m_colCount ; col ++ ) + { + sal_Int32 size = PQfsize( pResult, col ); + size = -1 == size ? 25 : size; + m_colDesc[col].displaySize = size; + + extractPrecisionAndScale( + PQfmod( pResult, col ), + & ( m_colDesc[col].precision ), + & ( m_colDesc[col].scale ) ); + char *name = PQfname( pResult, col ); + m_colDesc[col].name = OUString( name, strlen(name) , (*m_ppSettings)->encoding ); + m_colDesc[col].typeOid = PQftype( pResult, col ); + m_colDesc[col].type = com::sun::star::sdbc::DataType::LONGVARCHAR; + } +} + +// typedef std::hash_map< +// Oid, +// rtl::OUString, +// std::hash< Oid >, +// std::equal_to< Oid >, +// Allocator < std::pair< Oid, rtl::OUString > > > PqTypeMap; + + +void ResultSetMetaData::checkForTypes() +{ + if( ! m_checkedForTypes ) + { + Reference< XStatement > stmt = + extractConnectionFromStatement( m_origin->getStatement() )->createStatement(); + DisposeGuard guard( stmt ); + OUStringBuffer buf(128); + buf.appendAscii( "SELECT oid, typname, typtype FROM pg_type WHERE "); + for( int i = 0 ; i < m_colCount ; i ++ ) + { + if( i > 0 ) + buf.appendAscii( " OR " ); + int oid = m_colDesc[i].typeOid; + buf.appendAscii( "oid=" ); + buf.append( (sal_Int32) oid, 10 ); + } + Reference< XResultSet > rs = stmt->executeQuery( buf.makeStringAndClear() ); + Reference< XRow > xRow( rs, UNO_QUERY ); + while( rs->next() ) + { + sal_Int32 oid = xRow->getInt( 1 ); + OUString typeName = xRow->getString( 2 ); + OUString typType = xRow->getString( 3 ); + + sal_Int32 type = typeNameToDataType( typeName, typType ); + + for( int j = 0; j < m_colCount ; j ++ ) + { + if( m_colDesc[j].typeOid == oid ) + { + m_colDesc[j].typeName = typeName; + m_colDesc[j].type = type; + } + } + } + m_checkedForTypes = true; + } +} + +void ResultSetMetaData::checkTable() +{ + if( ! m_checkedForTable ) + { + m_checkedForTable = true; + if( m_tableName.getLength() ) + { + + Reference< com::sun::star::container::XNameAccess > tables = (*m_ppSettings)->tables; + if( ! tables.is() ) + { + + Reference< XTablesSupplier > supplier = + Reference< XTablesSupplier > ( + extractConnectionFromStatement( m_origin->getStatement() ), UNO_QUERY); + if( supplier.is() ) + tables = supplier->getTables(); + } + if( tables.is() ) + { + OUString name = getTableName( 1 ); +// if( tables->hasByName( name ) ) + tables->getByName( name ) >>= m_table; + } + } + } +} + +sal_Int32 ResultSetMetaData::getIntColumnProperty( const rtl::OUString & name, int index, int def ) +{ + sal_Int32 ret = def; // give defensive answers, when data is not available + try + { + MutexGuard guard( m_refMutex->mutex ); + checkColumnIndex( index ); + Reference< XPropertySet > set = getColumnByIndex( index ); + + if( set.is() ) + { + set->getPropertyValue( name ) >>= ret; + } + } + catch( com::sun::star::uno::Exception & e ) + { + } + return ret; +} + +sal_Bool ResultSetMetaData::getBoolColumnProperty( const rtl::OUString & name, int index, sal_Bool def ) +{ + sal_Bool ret = def; + try + { + MutexGuard guard( m_refMutex->mutex ); + checkColumnIndex( index ); + Reference< XPropertySet > set = getColumnByIndex( index ); + if( set.is() ) + { + set->getPropertyValue( name ) >>= ret; + } + } + catch( com::sun::star::uno::Exception & e ) + { + } + + return ret; +} + +Reference< com::sun::star::beans::XPropertySet > ResultSetMetaData::getColumnByIndex( int index ) +{ + Reference< XPropertySet > ret; + checkTable(); + if( m_table.is() ) + { + OUString columnName = getColumnName( index ); + Reference< XColumnsSupplier > supplier( m_table, UNO_QUERY ); + if( supplier.is() ) + { + Reference< XNameAccess > columns = supplier->getColumns(); + if( columns.is() && columns->hasByName( columnName ) ) + { + columns->getByName( columnName ) >>= ret; + } + } + } + return ret; +} + +// Methods +sal_Int32 ResultSetMetaData::getColumnCount( ) + throw (SQLException, RuntimeException) +{ + return m_colCount; +} + +sal_Bool ResultSetMetaData::isAutoIncrement( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + + sal_Bool ret = getBoolColumnProperty( getStatics().IS_AUTO_INCREMENT, column, sal_False ); + return ret; +} + +sal_Bool ResultSetMetaData::isCaseSensitive( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + + return sal_True; // ??? hmm, numeric types or +} + +sal_Bool ResultSetMetaData::isSearchable( sal_Int32 column ) throw (SQLException, RuntimeException) +{ + return sal_True; // mmm, what types are not searchable ? +} + +sal_Bool ResultSetMetaData::isCurrency( sal_Int32 column ) throw (SQLException, RuntimeException) +{ + return getBoolColumnProperty( getStatics().IS_CURRENCY, column, sal_False ); +} + +sal_Int32 ResultSetMetaData::isNullable( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return getIntColumnProperty( + getStatics().IS_NULLABLE, column, com::sun::star::sdbc::ColumnValue::NULLABLE_UNKNOWN ); +} + +sal_Bool ResultSetMetaData::isSigned( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return sal_True; // +} + +sal_Int32 ResultSetMetaData::getColumnDisplaySize( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( column ); + return m_colDesc[column-1].displaySize; +} + +::rtl::OUString ResultSetMetaData::getColumnLabel( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return getColumnName( column); +} + +::rtl::OUString ResultSetMetaData::getColumnName( sal_Int32 column ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( column ); + + return m_colDesc[column-1].name; +} + +::rtl::OUString ResultSetMetaData::getSchemaName( sal_Int32 column ) throw (SQLException, RuntimeException) +{ + return m_schemaName; +} + + + +sal_Int32 ResultSetMetaData::getPrecision( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( column ); + return m_colDesc[column-1].precision; +} + +sal_Int32 ResultSetMetaData::getScale( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkColumnIndex( column ); + return m_colDesc[column-1].scale; +} + +::rtl::OUString ResultSetMetaData::getTableName( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + rtl::OUString ret; + if( m_tableName.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.append( m_schemaName ); + buf.appendAscii( "." ); + buf.append( m_tableName ); + ret = buf.makeStringAndClear(); + } + return ret; +} + +::rtl::OUString ResultSetMetaData::getCatalogName( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + // can do this through XConnection.getCatalog() ! + return OUString(); +} +sal_Int32 ResultSetMetaData::getColumnType( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + int ret = getIntColumnProperty( getStatics().TYPE, column, -100 ); + if( -100 == ret ) + { + checkForTypes(); + if( com::sun::star::sdbc::DataType::LONGVARCHAR == m_colDesc[column-1].type && m_pResultSet ) + m_colDesc[column-1].type = m_pResultSet->guessDataType( column ); + ret = m_colDesc[column-1].type; + } + return ret; +} + +::rtl::OUString ResultSetMetaData::getColumnTypeName( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + ::rtl::OUString ret; // give defensive answers, when data is not available + try + { + MutexGuard guard( m_refMutex->mutex ); + checkColumnIndex( column ); + Reference< XPropertySet > set = getColumnByIndex( column ); + + if( set.is() ) + { + set->getPropertyValue( getStatics().TYPE_NAME ) >>= ret; + } + else + { + checkForTypes(); + ret = m_colDesc[column-1].typeName; + } + } + catch( com::sun::star::uno::Exception & e ) + { + } + return ret; +} + + +sal_Bool ResultSetMetaData::isReadOnly( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool ResultSetMetaData::isWritable( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return ! isReadOnly( column ); // what's the sense if this method ? +} + +sal_Bool ResultSetMetaData::isDefinitelyWritable( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return isWritable(column); // uhh, now it becomes really esoteric .... +} +::rtl::OUString ResultSetMetaData::getColumnServiceName( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return OUString(); +} + +void ResultSetMetaData::checkClosed() + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + // we never close +} + +void ResultSetMetaData::checkColumnIndex(sal_Int32 columnIndex) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_colCount ) + { + OUStringBuffer buf(128); + + buf.appendAscii( "pq_resultsetmetadata: index out of range (expected 1 to " ); + buf.append( m_colCount ); + buf.appendAscii( ", got " ); + buf.append( columnIndex ); + throw SQLException( + buf.makeStringAndClear(), *this, OUString(), 1, Any() ); + } +} + +} diff --git connectivity/source/drivers/postgresql/pq_resultsetmetadata.hxx connectivity/source/drivers/postgresql/pq_resultsetmetadata.hxx new file mode 100644 index 0000000..1c2eb43 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_resultsetmetadata.hxx @@ -0,0 +1,156 @@ +/************************************************************************* + * + * $RCSfile: pq_resultsetmetadata.hxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2006/05/01 19:19:07 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#ifndef _PQ_RESULTSETMETADATA_HXX_ +#define _PQ_RESULTSETMETADATA_HXX_ +#include + +#include "pq_connection.hxx" + +#include +#include + +#include + +namespace pq_sdbc_driver +{ + +struct ColDesc +{ + rtl::OUString name; + sal_Int32 precision; + sal_Int32 scale; + sal_Int32 displaySize; + Oid typeOid; + rtl::OUString typeName; + sal_Int32 type; +}; + +class ResultSet; + +typedef std::vector< ColDesc, Allocator< ColDesc > > ColDescVector; + + +class ResultSetMetaData : + public ::cppu::WeakImplHelper1 < com::sun::star::sdbc::XResultSetMetaData > +{ + ::rtl::Reference< RefCountedMutex > m_refMutex; + ConnectionSettings **m_ppSettings; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > m_origin; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_table; + ::rtl::OUString m_tableName; + ::rtl::OUString m_schemaName; + ColDescVector m_colDesc; + ResultSet *m_pResultSet; + + bool m_checkedForTable; + bool m_checkedForTypes; + + sal_Int32 m_colCount; + + void checkClosed() + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + void checkColumnIndex( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + void checkTable(); + void checkForTypes(); + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > getColumnByIndex( int index ); + + sal_Int32 getIntColumnProperty( const rtl::OUString & name, int index, int def ); + sal_Bool getBoolColumnProperty( const rtl::OUString & name, int index, sal_Bool def ); + +public: + ResultSetMetaData( + const ::rtl::Reference< RefCountedMutex > & reMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet > & origin, + ResultSet *pResultSet, + ConnectionSettings **pSettings, + PGresult *pResult, + const rtl::OUString &schemaName, + const rtl::OUString &tableName ); + +public: + // Methods + virtual sal_Int32 SAL_CALL getColumnCount( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isAutoIncrement( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isCaseSensitive( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isSearchable( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isCurrency( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL isNullable( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isSigned( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getColumnDisplaySize( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getColumnLabel( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getColumnName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSchemaName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getPrecision( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getScale( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTableName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getCatalogName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getColumnType( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getColumnTypeName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isReadOnly( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isWritable( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isDefinitelyWritable( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getColumnServiceName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); +}; + +} + +#endif diff --git connectivity/source/drivers/postgresql/pq_sequenceresultset.cxx connectivity/source/drivers/postgresql/pq_sequenceresultset.cxx new file mode 100644 index 0000000..584fafc --- /dev/null +++ connectivity/source/drivers/postgresql/pq_sequenceresultset.cxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * $RCSfile: pq_sequenceresultset.cxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2006/01/22 15:14:31 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include "pq_sequenceresultset.hxx" +#include "pq_sequenceresultsetmetadata.hxx" + + +using rtl::OUString; + +using com::sun::star::sdbc::XResultSetMetaData; + +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Any; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +void SequenceResultSet::checkClosed() + throw ( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) +{ + // we never close :o) +} + + +Any SequenceResultSet::getValue( sal_Int32 columnIndex ) +{ + m_wasNull = ! m_data[m_row][columnIndex -1 ].hasValue(); + return m_data[m_row][columnIndex -1 ]; +} + +SequenceResultSet::SequenceResultSet( + const ::rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner, + const Sequence< OUString > &colNames, + const Sequence< Sequence< Any > > &data, + const Reference< com::sun::star::script::XTypeConverter > & tc, + const ColumnMetaDataVector *pVec) : + BaseResultSet( mutex, owner, data.getLength(), colNames.getLength(),tc ), + m_data(data ), + m_columnNames( colNames ) +{ + if( pVec ) + { + m_meta = new SequenceResultSetMetaData( mutex, *pVec, m_columnNames.getLength() ); + } +} + +SequenceResultSet::~SequenceResultSet() +{ + +} + +void SequenceResultSet::close( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + // a noop +} + +Reference< XResultSetMetaData > SAL_CALL SequenceResultSet::getMetaData( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + if( ! m_meta.is() ) + { + // Oh no, not again + throw ::com::sun::star::sdbc::SQLException( + ASCII_STR( "pq_sequenceresultset: no meta supported " ), *this, + OUString(), 1, Any() ); + } + return m_meta; +} + + +sal_Int32 SAL_CALL SequenceResultSet::findColumn( + const ::rtl::OUString& columnName ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + // no need to guard, as all members are readonly ! + sal_Int32 ret = -1; + for( int i = 0 ;i < m_fieldCount ; i ++ ) + { + if( columnName == m_columnNames[i] ) + { + ret = i+1; + break; + } + } + return ret; +} +} diff --git connectivity/source/drivers/postgresql/pq_sequenceresultset.hxx connectivity/source/drivers/postgresql/pq_sequenceresultset.hxx new file mode 100644 index 0000000..5eb5402 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_sequenceresultset.hxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * $RCSfile: pq_sequenceresultset.hxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2006/01/22 15:14:32 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#ifndef _PG_SEQUENCERESULTSET_HXX_ +#define _PG_SEQUENCERESULTSET_HXX_ + +#include +#include + +#include +#include +#include +#include +#include "pq_connection.hxx" +#include "pq_baseresultset.hxx" +#include "pq_statics.hxx" + +namespace pq_sdbc_driver +{ + +// static const sal_Int32 RESULTSET_CURSOR_NAME = 0; +// static const sal_Int32 RESULTSET_ESCAPE_PROCESSING = 1; +// static const sal_Int32 RESULTSET_FETCH_DIRECTION = 2; +// static const sal_Int32 RESULTSET_FETCH_SIZE = 3; +// static const sal_Int32 RESULTSET_RESULT_SET_CONCURRENCY = 4; +// static const sal_Int32 RESULTSET_RESULT_SET_TYPE = 5; + +//#define RESULTSET_SIZE 6 +class ResultSetGuard; + +class SequenceResultSet : public BaseResultSet +{ +protected: + ::com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > > m_data; + + ::com::sun::star::uno::Sequence< ::rtl::OUString > m_columnNames; + ::com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSetMetaData > m_meta; + +protected: + /** mutex should be locked before called + */ + virtual void checkClosed() + throw ( com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException ); + + /** unchecked, acquire mutex before calling + */ + virtual ::com::sun::star::uno::Any getValue( sal_Int32 columnIndex ); + +public: + SequenceResultSet( + const ::rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner, + const com::sun::star::uno::Sequence< rtl::OUString > &colNames, + const com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< com::sun::star::uno::Any > > &data, + const com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter > &tc, + const ColumnMetaDataVector *pVec = 0); + ~SequenceResultSet(); + +public: // XCloseable + virtual void SAL_CALL close( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XResultSetMetaDataSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL getMetaData( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XColumnLocate + virtual sal_Int32 SAL_CALL findColumn( const ::rtl::OUString& columnName ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_sequenceresultsetmetadata.cxx connectivity/source/drivers/postgresql/pq_sequenceresultsetmetadata.cxx new file mode 100644 index 0000000..d94a3be --- /dev/null +++ connectivity/source/drivers/postgresql/pq_sequenceresultsetmetadata.cxx @@ -0,0 +1,182 @@ +#include "pq_sequenceresultsetmetadata.hxx" + +#include + +using rtl::OUStringBuffer; +using rtl::OUString; +using com::sun::star::uno::Any; + +using com::sun::star::uno::RuntimeException; + +using com::sun::star::sdbc::SQLException; + +namespace pq_sdbc_driver +{ + +SequenceResultSetMetaData::SequenceResultSetMetaData( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ColumnMetaDataVector &metaDataVector, + int colCount ) : + m_refMutex( refMutex ), + m_colCount( colCount ), + m_columnData( metaDataVector ) +{ +} + + +// Methods +sal_Int32 SequenceResultSetMetaData::getColumnCount( ) + throw (SQLException, RuntimeException) +{ + return m_colCount; +} + +sal_Bool SequenceResultSetMetaData::isAutoIncrement( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].isAutoIncrement; +} + +sal_Bool SequenceResultSetMetaData::isCaseSensitive( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + + return sal_True; // ??? hmm, numeric types or +} + +sal_Bool SequenceResultSetMetaData::isSearchable( sal_Int32 column ) throw (SQLException, RuntimeException) +{ + return sal_True; // mmm, what types are not searchable ? +} + +sal_Bool SequenceResultSetMetaData::isCurrency( sal_Int32 column ) throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].isCurrency; +} + +sal_Int32 SequenceResultSetMetaData::isNullable( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].isNullable; +} + +sal_Bool SequenceResultSetMetaData::isSigned( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return sal_True; // +} + +sal_Int32 SequenceResultSetMetaData::getColumnDisplaySize( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return 50; +} + +::rtl::OUString SequenceResultSetMetaData::getColumnLabel( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].columnName; +} + +::rtl::OUString SequenceResultSetMetaData::getColumnName( sal_Int32 column ) throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].columnName; +} + +::rtl::OUString SequenceResultSetMetaData::getSchemaName( sal_Int32 column ) throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].schemaTableName; +} + + + +sal_Int32 SequenceResultSetMetaData::getPrecision( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].precision; +} + +sal_Int32 SequenceResultSetMetaData::getScale( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].scale; +} + +::rtl::OUString SequenceResultSetMetaData::getTableName( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].tableName; +} + +::rtl::OUString SequenceResultSetMetaData::getCatalogName( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + // can do this through XConnection.getCatalog() ! + return OUString(); +} +sal_Int32 SequenceResultSetMetaData::getColumnType( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].type; +} + +::rtl::OUString SequenceResultSetMetaData::getColumnTypeName( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + checkColumnIndex( column ); + return m_columnData[column-1].typeName; +} + + +sal_Bool SequenceResultSetMetaData::isReadOnly( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return sal_False; +} + +sal_Bool SequenceResultSetMetaData::isWritable( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return ! isReadOnly( column ); // what's the sense if this method ? +} + +sal_Bool SequenceResultSetMetaData::isDefinitelyWritable( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return isWritable(column); // uhh, now it becomes really esoteric .... +} +::rtl::OUString SequenceResultSetMetaData::getColumnServiceName( sal_Int32 column ) + throw (SQLException, RuntimeException) +{ + return OUString(); +} + + +void SequenceResultSetMetaData::checkColumnIndex(sal_Int32 columnIndex) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_colCount ) + { + OUStringBuffer buf(128); + + buf.appendAscii( "pq_sequenceresultsetmetadata: index out of range (expected 1 to " ); + buf.append( m_colCount ); + buf.appendAscii( ", got " ); + buf.append( columnIndex ); + throw SQLException( + buf.makeStringAndClear(), *this, OUString(), 1, Any() ); + } +} + + +} diff --git connectivity/source/drivers/postgresql/pq_sequenceresultsetmetadata.hxx connectivity/source/drivers/postgresql/pq_sequenceresultsetmetadata.hxx new file mode 100644 index 0000000..533863c --- /dev/null +++ connectivity/source/drivers/postgresql/pq_sequenceresultsetmetadata.hxx @@ -0,0 +1,53 @@ +#include +#include + +#include "pq_connection.hxx" +#include "pq_statics.hxx" + +namespace pq_sdbc_driver +{ + class SequenceResultSetMetaData : + public ::cppu::WeakImplHelper1 < com::sun::star::sdbc::XResultSetMetaData > + { + ::rtl::Reference< RefCountedMutex > m_refMutex; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > m_origin; + ::rtl::OUString m_tableName; + ::rtl::OUString m_schemaName; + ColumnMetaDataVector m_columnData; + sal_Int32 m_colCount; + + void checkColumnIndex( sal_Int32 columnIndex ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + public: + SequenceResultSetMetaData( + const ::rtl::Reference< RefCountedMutex > & reMutex, + const ColumnMetaDataVector &vec, + int colCount ); + + public: + // Methods + virtual sal_Int32 SAL_CALL getColumnCount( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isAutoIncrement( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isCaseSensitive( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isSearchable( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isCurrency( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL isNullable( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isSigned( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getColumnDisplaySize( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getColumnLabel( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getColumnName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSchemaName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getPrecision( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getScale( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTableName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getCatalogName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getColumnType( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getColumnTypeName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isReadOnly( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isWritable( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isDefinitelyWritable( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getColumnServiceName( sal_Int32 column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + }; + +} diff --git connectivity/source/drivers/postgresql/pq_statement.cxx connectivity/source/drivers/postgresql/pq_statement.cxx new file mode 100644 index 0000000..b60edfc --- /dev/null +++ connectivity/source/drivers/postgresql/pq_statement.cxx @@ -0,0 +1,1063 @@ +/************************************************************************* + * + * $RCSfile: pq_statement.cxx,v $ + * + * $Revision: 1.1.2.7 $ + * + * last change: $Author: jbu $ $Date: 2007/08/26 20:40:40 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#include "pq_statement.hxx" +#include "pq_fakedupdateableresultset.hxx" +#include "pq_updateableresultset.hxx" +#include "pq_tools.hxx" +#include "pq_statics.hxx" + +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + + +using osl::Mutex; +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; +using rtl::OStringToOUString; +using rtl::OString; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Exception; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::UNO_QUERY; + +using com::sun::star::lang::IllegalArgumentException; + +using com::sun::star::sdbc::XWarningsSupplier; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XGeneratedResultSet; +using com::sun::star::sdbc::XConnection; +using com::sun::star::sdbc::SQLException; + +using com::sun::star::sdbcx::XColumnsSupplier; +using com::sun::star::sdbcx::XTablesSupplier; +using com::sun::star::sdbcx::XKeysSupplier; + +using com::sun::star::beans::Property; +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::XFastPropertySet; +using com::sun::star::beans::XMultiPropertySet; + +using com::sun::star::container::XNameAccess; +using com::sun::star::container::XEnumerationAccess; +using com::sun::star::container::XEnumeration; +using com::sun::star::container::XIndexAccess; + +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) +namespace pq_sdbc_driver +{ +static ::cppu::IPropertyArrayHelper & getStatementPropertyArrayHelper() +{ + static ::cppu::IPropertyArrayHelper *pArrayHelper; + if( ! pArrayHelper ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pArrayHelper ) + { + static Property aTable[] = + { + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("CursorName") ), 0, + ::getCppuType( (OUString *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("EscapeProcessing") ), 1, + ::getBooleanCppuType() , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("FetchDirection") ), 2, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("FetchSize") ), 3, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("MaxFieldSize") ), 4, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("MaxRows") ), 5, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("QueryTimeOut") ), 6, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetConcurrency") ), 7, + ::getCppuType( (sal_Int32 *)0) , 0 ), + Property( + OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetType") ), 8, + ::getCppuType( (sal_Int32 *)0) , 0 ) + }; + OSL_ASSERT( sizeof(aTable)/ sizeof(Property) == STATEMENT_SIZE ); + static ::cppu::OPropertyArrayHelper arrayHelper( aTable, STATEMENT_SIZE, sal_True ); + pArrayHelper = &arrayHelper; + } + } + return *pArrayHelper; +} + +Statement::Statement( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< XConnection > & conn, + struct ConnectionSettings *pSettings ) + : OComponentHelper( refMutex->mutex ), + OPropertySetHelper( OComponentHelper::rBHelper ), + m_refMutex( refMutex ), + m_connection( conn ), + m_pSettings( pSettings ), + m_lastOidInserted( InvalidOid ) +{ + m_props[STATEMENT_QUERY_TIME_OUT] = makeAny( (sal_Int32)0 ); + m_props[STATEMENT_MAX_ROWS] = makeAny( (sal_Int32)0 ); + m_props[STATEMENT_RESULT_SET_CONCURRENCY] = makeAny( + com::sun::star::sdbc::ResultSetConcurrency::READ_ONLY ); + m_props[STATEMENT_RESULT_SET_TYPE] = makeAny( + com::sun::star::sdbc::ResultSetType::SCROLL_INSENSITIVE ); +} + +Statement::~Statement() +{ + POSTGRE_TRACE( "dtor Statement" ); +} + +void Statement::checkClosed() throw (SQLException, RuntimeException ) +{ + if( ! m_pSettings || ! m_pSettings->pConnection ) + throw SQLException( + ASCII_STR("pq_driver: Statement or connection has already been closed !" ), + *this, OUString(),1,Any()); +} + +Any Statement::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = OComponentHelper::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( reqType, + static_cast< XWarningsSupplier * > ( this ), + static_cast< XStatement * > ( this ), + static_cast< com::sun::star::sdbc::XResultSetMetaDataSupplier * > ( this ), + static_cast< XCloseable * > ( this ), + static_cast< XPropertySet * > ( this ), + static_cast< XMultiPropertySet * > ( this ), + static_cast< XGeneratedResultSet * > ( this ), + static_cast< XFastPropertySet * > ( this ) ); + return ret; +} + + +Sequence< Type > Statement::getTypes() throw ( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< XWarningsSupplier> *) 0 ), + getCppuType( (Reference< XStatement> *) 0 ), + getCppuType( (Reference< com::sun::star::sdbc::XResultSetMetaDataSupplier> *) 0 ), + getCppuType( (Reference< XCloseable> *) 0 ), + getCppuType( (Reference< XPropertySet >*) 0 ), + getCppuType( (Reference< XFastPropertySet > *) 0 ), + getCppuType( (Reference< XMultiPropertySet > *) 0 ), + getCppuType( (Reference< XGeneratedResultSet > *) 0 ), + OComponentHelper::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> Statement::getImplementationId() throw ( RuntimeException ) +{ + static cppu::OImplementationId *pId; + if( ! pId ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( ! pId ) + { + static cppu::OImplementationId id(sal_False); + pId = &id; + } + } + return pId->getImplementationId(); +} + +void Statement::close( ) throw (SQLException, RuntimeException) +{ + // let the connection die without acquired mutex ! + Reference< XConnection > r; + Reference< XCloseable > resultSet; + { + MutexGuard guard( m_refMutex->mutex ); + m_pSettings = 0; + r = m_connection; + m_connection.clear(); + + resultSet = m_lastResultset; + m_lastResultset.clear(); + } + if( resultSet.is() ) + { + resultSet->close(); + POSTGRE_TRACE( "statement closed" ); + } + +} + +void Statement::raiseSQLException( + const OUString & sql, const char * errorMsg, const char *errorType ) + throw( SQLException ) +{ + OUStringBuffer buf(128); + buf.appendAscii( "pq_driver: "); + if( errorType ) + { + buf.appendAscii( "[" ); + buf.appendAscii( errorType ); + buf.appendAscii( "]" ); + } + buf.append( + rtl::OUString( errorMsg, strlen(errorMsg) , m_pSettings->encoding ) ); + buf.appendAscii( " (caused by statement '" ); + buf.append( sql ); + buf.appendAscii( "')" ); + OUString error = buf.makeStringAndClear(); + log( m_pSettings, LogLevel::ERROR, error ); + throw SQLException( error, *this, OUString(), 1, Any() ); +} + +Reference< XResultSet > Statement::executeQuery(const OUString& sql ) + throw (SQLException, RuntimeException) +{ + Reference< XCloseable > lastResultSetHolder = m_lastResultset; + if( lastResultSetHolder.is() ) + lastResultSetHolder->close(); + + if( ! execute( sql ) ) + { + raiseSQLException( sql, "not a query" ); + } + return Reference< XResultSet > ( m_lastResultset, com::sun::star::uno::UNO_QUERY ); +} + +sal_Int32 Statement::executeUpdate( const OUString& sql ) + throw (SQLException, RuntimeException) +{ + if( execute( sql ) ) + { + raiseSQLException( sql, "not a command" ); + } + return m_multipleResultUpdateCount; +} + + +static void raiseSQLException( + ConnectionSettings *pSettings, + const Reference< XInterface> & owner, + const OString & sql, + const char * errorMsg, + const char *errorType = 0 ) + throw( SQLException ) +{ + OUStringBuffer buf(128); + buf.appendAscii( "pq_driver: "); + if( errorType ) + { + buf.appendAscii( "[" ); + buf.appendAscii( errorType ); + buf.appendAscii( "]" ); + } + buf.append( + rtl::OUString( errorMsg, strlen(errorMsg) , pSettings->encoding ) ); + buf.appendAscii( " (caused by statement '" ); + buf.append( rtl::OStringToOUString( sql, pSettings->encoding ) ); + buf.appendAscii( "')" ); + OUString error = buf.makeStringAndClear(); + log( pSettings, LogLevel::ERROR, error ); + throw SQLException( error, owner, OUString(), 1, Any() ); +} + + +// returns the elements of the primary key of the given table +// static Sequence< Reference< com::sun::star::beans::XPropertySet > > lookupKeys( +static Sequence< ::rtl::OUString > lookupKeys( + const Reference< com::sun::star::container::XNameAccess > &tables, + const OUString & table, + OUString *pSchema, + OUString *pTable, + ConnectionSettings *pSettings) +{ + Sequence< ::rtl::OUString > ret; + Reference< XKeysSupplier > keySupplier; + Statics & st = getStatics(); + + if( tables->hasByName( table ) ) + tables->getByName( table ) >>= keySupplier; + else if( -1 == table.indexOf( '.' ) ) + { + // it wasn't a fully qualified name. Now need to skip through all tables. + Reference< XEnumerationAccess > enumerationAccess = + Reference< XEnumerationAccess > ( tables, UNO_QUERY ); + + Reference< com::sun::star::container::XEnumeration > enumeration = + enumerationAccess->createEnumeration(); + while( enumeration->hasMoreElements() ) + { + Reference< XPropertySet > set; + enumeration->nextElement() >>= set; + OUString name; +// ::rtl::OUString schema; + + if( set->getPropertyValue( st.NAME ) >>= name ) + { +// printf( "searching %s %s\n", +// OUStringToOString( schema, RTL_TEXTENCODING_ASCII_US ).getStr(), +// OUStringToOString( name, RTL_TEXTENCODING_ASCII_US ).getStr() ); + if( name == table ) + { + + if( keySupplier.is() ) + { + // is ambigous, as I don't know postgresql searchpath, + // I can't continue here, as I may write to a different table + keySupplier.clear(); + if( isLog( pSettings, LogLevel::INFO ) ) + { + rtl::OStringBuffer buf( 128 ); + buf.append( "Can't offer updateable result set because table " ); + buf.append( OUStringToOString(name, pSettings->encoding) ); + buf.append( " is duplicated, add schema to resolve ambiguity" ); + log( pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() ); + } + break; + } + keySupplier = Reference< XKeysSupplier > ( set, UNO_QUERY ); + } + } + } + } + else + { + if( isLog( pSettings, LogLevel::INFO ) ) + { + rtl::OStringBuffer buf( 128 ); + buf.append( "Can't offer updateable result set ( table " ); + buf.append( OUStringToOString(table, pSettings->encoding) ); + buf.append( " is unknown)" ); + log( pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() ); + } + } + + if( keySupplier.is() ) + { + Reference< XPropertySet > set( keySupplier, UNO_QUERY ); + set->getPropertyValue( getStatics().NAME ) >>= (*pTable); + set->getPropertyValue( getStatics().SCHEMA_NAME ) >>= (*pSchema ); + set.clear(); + + Reference< XEnumerationAccess > keys ( keySupplier->getKeys(), UNO_QUERY ); + Reference< XEnumeration > enumeration = keys->createEnumeration(); + while( enumeration->hasMoreElements() ) + { + enumeration->nextElement() >>= set; + sal_Int32 keyType; + if( (set->getPropertyValue( st.TYPE ) >>= keyType ) && + keyType == com::sun::star::sdbcx::KeyType::PRIMARY ) + { + Reference< XColumnsSupplier > columns( set, UNO_QUERY ); + Reference< XIndexAccess > indexAccess = + Reference< XIndexAccess > ( columns->getColumns(), UNO_QUERY ); + + int length = indexAccess->getCount(); + ret.realloc( length ); +// printf( "primary key for Table %s is ", +// OUStringToOString( table, RTL_TEXTENCODING_ASCII_US ).getStr() ); + for( int i = 0 ; i < length ; i ++ ) + { + indexAccess->getByIndex( i ) >>= set; + OUString name; + set->getPropertyValue( st.NAME ) >>= name; + ret[i] = name; +// printf( "%s," , OUStringToOString( name, RTL_TEXTENCODING_ASCII_US ).getStr() ); + } +// printf( "\n" ); + } + } + if( ! ret.getLength() ) + { + if( isLog( pSettings, LogLevel::INFO ) ) + { + rtl::OStringBuffer buf( 128 ); + buf.append( "Can't offer updateable result set ( table " ); + buf.append( OUStringToOString(table, pSettings->encoding) ); + buf.append( " does not have a primary key)" ); + log( pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() ); + } + } + } + return ret; +} + +bool executePostgresCommand( const rtl::OString & cmd, struct CommandData *data ) +{ + ConnectionSettings *pSettings = *(data->ppSettings); + + sal_Int32 duration = osl_getGlobalTimer(); + PGresult *result = PQexec( pSettings->pConnection, cmd.getStr() ); + duration = osl_getGlobalTimer() - duration; + if( ! result ) + raiseSQLException( + pSettings, data->owner, cmd, PQerrorMessage( pSettings->pConnection ) ); + + ExecStatusType state = PQresultStatus( result ); + *(data->pLastOidInserted) = 0; + *(data->pLastTableInserted) = rtl::OUString(); + *(data->pLastQuery) = cmd; + + sal_Bool ret = sal_False; + switch( state ) + { + case PGRES_COMMAND_OK: + { + *(data->pMultipleResultUpdateCount) = atoi( PQcmdTuples( result ) ); + *(data->pMultipleResultAvailable) = sal_False; + + // in case an oid value is available, we retrieve it + *(data->pLastOidInserted) = PQoidValue( result ); + + // in case it was a single insert, extract the name of the table, + // otherwise the table name is empty + *(data->pLastTableInserted) = + extractTableFromInsert( OStringToOUString( cmd, pSettings->encoding ) ); + if( isLog( pSettings, LogLevel::SQL ) ) + { + rtl::OStringBuffer buf( 128 ); + buf.append( "executed command '" ); + buf.append( cmd.getStr() ); + buf.append( "' sucessfully (" ); + buf.append( *( data->pMultipleResultUpdateCount ) ); + buf.append( ")" ); + buf.append( ", duration=" ); + buf.append( duration ); + buf.append( "ms" ); + if( *(data->pLastOidInserted) ) + { + buf.append( ", usedOid=" ); + buf.append( *(data->pLastOidInserted) , 10 ); + buf.append( ", diagnosedTable=" ); + buf.append( + OUStringToOString( *data->pLastTableInserted, pSettings->encoding ) ); + } + log( pSettings, LogLevel::SQL, buf.makeStringAndClear().getStr() ); + } + PQclear( result ); + break; + } + case PGRES_TUPLES_OK: // success + { + // In case it is a single table, it has a primary key and all columns + // belonging to the primary key are in the result set, allow updateable result sets + // otherwise, don't + rtl::OUString table, schema; + Sequence< OUString > sourceTableKeys; + OStringVector vec; + tokenizeSQL( cmd, vec ); + OUString sourceTable = + OStringToOUString( + extractSingleTableFromSelect( vec ), pSettings->encoding ); + + if( data->concurrency == + com::sun::star::sdbc::ResultSetConcurrency::UPDATABLE ) + { + OString aReason; + if( sourceTable.getLength() ) + { + sourceTableKeys = lookupKeys( + pSettings->tables.is() ? + pSettings->tables : data->tableSupplier->getTables() , + sourceTable, + &schema, + &table, + pSettings); + + // check, whether the columns are in the result set (required !) + int i; + for( i = 0 ; i < sourceTableKeys.getLength() ; i ++ ) + { + if( -1 == PQfnumber( + result, + OUStringToOString( sourceTableKeys[i] , + pSettings->encoding ).getStr()) ) + { + break; + } + } + + if( sourceTableKeys.getLength() && i == sourceTableKeys.getLength() ) + { + *(data->pLastResultset) = + UpdateableResultSet::createFromPGResultSet( + data->refMutex, data->owner, data->ppSettings, result, + schema, table,sourceTableKeys ); + } + else if( ! table.getLength() ) + { + rtl::OStringBuffer buf( 128 ); + buf.append( + RTL_CONSTASCII_STRINGPARAM( + "can't support updateable resultset, because a single table in the " + "WHERE part of the statement could not be identified (" ) ); + buf.append( cmd ); + buf.append( RTL_CONSTASCII_STRINGPARAM( "." ) ); + aReason = buf.makeStringAndClear(); + } + else if( sourceTableKeys.getLength() ) + { + ::rtl::OStringBuffer buf( 128 ); + buf.append( + RTL_CONSTASCII_STRINGPARAM( + "can't support updateable resultset for table " ) ); + buf.append( rtl::OUStringToOString( schema, pSettings->encoding ) ); + buf.append( RTL_CONSTASCII_STRINGPARAM( "." ) ); + buf.append( rtl::OUStringToOString( table, pSettings->encoding ) ); + buf.append( RTL_CONSTASCII_STRINGPARAM( ", because resultset does not contain a part of the primary key ( column " ) ); + buf.append( rtl::OUStringToOString( sourceTableKeys[i], pSettings->encoding ) ); + buf.append( RTL_CONSTASCII_STRINGPARAM( " is missing )") ); + aReason = buf.makeStringAndClear(); + } + else + { + + ::rtl::OStringBuffer buf( 128 ); + buf.append( + RTL_CONSTASCII_STRINGPARAM( + "can't support updateable resultset for table " ) ); + buf.append( rtl::OUStringToOString( schema, pSettings->encoding ) ); + buf.append( RTL_CONSTASCII_STRINGPARAM( "." ) ); + buf.append( rtl::OUStringToOString( table, pSettings->encoding ) ); + buf.append( RTL_CONSTASCII_STRINGPARAM( ", because resultset table does not have a primary key " ) ); + aReason = buf.makeStringAndClear(); + } + } + else + { + ::rtl::OStringBuffer buf( 128 ); + buf.append( + RTL_CONSTASCII_STRINGPARAM( + "can't support updateable result for selects with multiple tables (" ) ); + buf.append( cmd ); + buf.append( RTL_CONSTASCII_STRINGPARAM( ")" ) ); + log( pSettings, LogLevel::SQL, buf.makeStringAndClear().getStr() ); + } + if( ! (*(data->pLastResultset)).is() ) + { + if( isLog( pSettings, LogLevel::ERROR ) ) + { + log( pSettings, LogLevel::ERROR, aReason.getStr()); + } + + // TODO: How to react here correctly ? + // remove this piece of code + *(data->pLastResultset) = + new FakedUpdateableResultSet( + data->refMutex, data->owner, + data->ppSettings,result, schema, table, + OStringToOUString( aReason, pSettings->encoding) ); + } + + } + else if( sourceTable.getLength() && -1 != sourceTable.indexOf( '.' ) ) + { + splitConcatenatedIdentifier( sourceTable, &schema, &table ); + } + + sal_Int32 returnedRows = PQntuples( result ); + if( ! data->pLastResultset->is() ) + *(data->pLastResultset) = + Reference< XCloseable > ( + new ResultSet( + data->refMutex, data->owner, + data->ppSettings,result, schema, table ) ); + *(data->pMultipleResultAvailable) = sal_True; + ret = sal_True; + if( isLog( pSettings, LogLevel::SQL ) ) + { + rtl::OStringBuffer buf( 128 ); + buf.append( RTL_CONSTASCII_STRINGPARAM("executed query '") ); + buf.append( cmd ); + buf.append( RTL_CONSTASCII_STRINGPARAM("' sucessfully") ); + buf.append( RTL_CONSTASCII_STRINGPARAM(", duration=") ); + buf.append( duration ); + buf.append( RTL_CONSTASCII_STRINGPARAM("ms, returnedRows=") ); + buf.append( returnedRows ); + buf.append( RTL_CONSTASCII_STRINGPARAM("." ) ); + log( pSettings, LogLevel::SQL, buf.makeStringAndClear().getStr() ); + } + break; + } + case PGRES_EMPTY_QUERY: + case PGRES_COPY_OUT: + case PGRES_COPY_IN: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: + case PGRES_FATAL_ERROR: + default: + raiseSQLException( + pSettings, data->owner, cmd, PQresultErrorMessage( result ) , PQresStatus( state ) ); + } + return ret; + +} + +static Sequence< OUString > getPrimaryKeyColumnNames( + const Reference< XConnection > & connection, const OUString &schemaName, const OUString &tableName ) +{ + Sequence< OUString > ret; + + Int2StringMap mapIndex2Name; + fillAttnum2attnameMap( mapIndex2Name, connection, schemaName, tableName ); + + // retrieve the primary key ... + Reference< XPreparedStatement > stmt = connection->prepareStatement( + ASCII_STR( + "SELECT conkey " // 7 + "FROM pg_constraint INNER JOIN pg_class ON conrelid = pg_class.oid " + "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid " + "LEFT JOIN pg_class AS class2 ON confrelid = class2.oid " + "LEFT JOIN pg_namespace AS nmsp2 ON class2.relnamespace=nmsp2.oid " + "WHERE pg_class.relname = ? AND pg_namespace.nspname = ? AND pg_constraint.contype='p'" ) ); + DisposeGuard guard( stmt ); + Reference< XParameters > paras( stmt, UNO_QUERY ); + paras->setString( 1 , tableName ); + paras->setString( 2 , schemaName ); + Reference< XResultSet > rs = stmt->executeQuery(); + Reference< XRow > xRow( rs , UNO_QUERY ); + + if( rs->next() ) + { + ret = convertMappedIntArray2StringArray( mapIndex2Name, string2intarray(xRow->getString( 1 ) ) ); + } + return ret; +} + +static void getAutoValues( + String2StringMap & result, + const Reference< XConnection > & connection, + const OUString &schemaName, + const OUString & tableName ) +{ + Reference< XPreparedStatement > stmt = connection->prepareStatement( + ASCII_STR("SELECT pg_attribute.attname, pg_attrdef.adsrc " + "FROM pg_class, pg_namespace, pg_attribute " + "LEFT JOIN pg_attrdef ON pg_attribute.attrelid = pg_attrdef.adrelid AND " + "pg_attribute.attnum = pg_attrdef.adnum " + "WHERE pg_attribute.attrelid = pg_class.oid AND " + "pg_class.relnamespace = pg_namespace.oid AND " + "pg_namespace.nspname = ? AND " + "pg_class.relname LIKE ? AND " + "pg_attrdef.adsrc != ''" + ) ); + DisposeGuard guard( stmt ); + Reference< XParameters > paras( stmt, UNO_QUERY ); + paras->setString( 1 , schemaName ); + paras->setString( 2 , tableName ); + Reference< XResultSet > rs = stmt->executeQuery(); + Reference< XRow > xRow( rs , UNO_QUERY ); + + while( rs->next() ) + { + result[ OUStringToOString( xRow->getString( 1 ), RTL_TEXTENCODING_ASCII_US) ] = + OUStringToOString( xRow->getString(2), RTL_TEXTENCODING_ASCII_US ); + } +} + +Reference< XResultSet > getGeneratedValuesFromLastInsert( + ConnectionSettings *pConnectionSettings, + const Reference< XConnection > &connection, + sal_Int32 nLastOid, + const rtl::OUString & lastTableInserted, + const rtl::OString & lastQuery ) +{ + Reference< XResultSet > ret; + OUString query; + OUString schemaName, tableName; + splitConcatenatedIdentifier( + lastTableInserted, &schemaName, &tableName ); + + if( nLastOid && lastTableInserted.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT * FROM " ) ); + if( schemaName.getLength() ) + bufferQuoteQualifiedIdentifier(buf, schemaName,tableName ); + else + bufferQuoteIdentifier( buf, lastTableInserted ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " WHERE oid = " ) ); + buf.append( nLastOid , 10 ); + query = buf.makeStringAndClear(); + } + else if ( lastTableInserted.getLength() && lastQuery.getLength() ) + { + // extract nameValue Pairs + String2StringMap namedValues; + extractNameValuePairsFromInsert( namedValues, lastQuery ); + + // debug ... +// rtl::OStringBuffer buf( 128); +// buf.append( "extracting name/value from '" ); +// buf.append( lastQuery.getStr() ); +// buf.append( "' to [" ); +// for( String2StringMap::iterator ii = namedValues.begin() ; ii != namedValues.end() ; ++ii ) +// { +// buf.append( ii->first.getStr() ); +// buf.append( "=" ); +// buf.append( ii->second.getStr() ); +// buf.append( "," ); +// } +// buf.append( "]\n" ); +// printf( buf.makeStringAndClear() ); + + // TODO: make also unqualified tables names work here. Have a look at 2.8.3. The Schema Search Path + // in postgresql doc + + Sequence< OUString > keyColumnNames = getPrimaryKeyColumnNames( connection, schemaName, tableName ); + if( keyColumnNames.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT * FROM " ) ); + bufferQuoteQualifiedIdentifier(buf, schemaName,tableName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " WHERE " ) ); + bool additionalCondition = false; + String2StringMap autoValues; + for( int i = 0 ; i < keyColumnNames.getLength() ; i ++ ) + { + OUString value; + OString columnName = OUStringToOString( keyColumnNames[i], pConnectionSettings->encoding ); + String2StringMap::iterator ii = namedValues.begin(); + for( ; ii != namedValues.end() ; ++ii ) + { + if( columnName.equalsIgnoreAsciiCase( ii->first ) ) + { + value = OStringToOUString( ii->second , pConnectionSettings->encoding ); + break; + } + } + + // check, if a column of the primary key was not inserted explicitly, + if( ii == namedValues.end() ) + { + + if( autoValues.begin() == autoValues.end() ) + { + getAutoValues( autoValues, connection, schemaName, tableName ); + } + // this could mean, that the column is a default or auto value, check this ... + String2StringMap::iterator ii = autoValues.begin(); + for( ; ii != autoValues.end() ; ++ii ) + { + if( columnName.equalsIgnoreAsciiCase( ii->first ) ) + { + // it is indeed an auto value. + value = OStringToOUString(ii->second, RTL_TEXTENCODING_ASCII_US ); + // check, whether it is a sequence + + if( rtl_str_shortenedCompare_WithLength( + ii->second.getStr(), ii->second.getLength(), + RTL_CONSTASCII_STRINGPARAM( "nextval(" ), 8 ) == 0 ) + { + // retrieve current sequence value: + OUStringBuffer myBuf(128 ); + myBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT currval(" ) ); + myBuf.appendAscii( &(ii->second.getStr()[8])); + value = querySingleValue( connection, myBuf.makeStringAndClear() ); + } + break; + } + } + if( ii == autoValues.end() ) + { + // it even was no autovalue, no sense to continue as we can't query the + // inserted row + buf = OUStringBuffer(); + break; + } + } + + if( additionalCondition ) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " AND " ) ); + bufferQuoteIdentifier( buf, keyColumnNames[i] ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ) ); + buf.append( value ); + additionalCondition = true; + } + query = buf.makeStringAndClear(); + } + } + + if( query.getLength() ) + { + Reference< com::sun::star::sdbc::XStatement > stmt = connection->createStatement(); + ret = stmt->executeQuery( query ); + } + + return ret; + +} + +sal_Bool Statement::execute( const OUString& sql ) + throw (SQLException, RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + OString cmd = rtl::OUStringToOString( sql, m_pSettings->encoding ); + + m_lastResultset.clear(); + m_lastTableInserted = rtl::OUString(); + + struct CommandData data; + data.refMutex = m_refMutex; + data.ppSettings = &m_pSettings; + data.pLastOidInserted = &m_lastOidInserted; + data.pLastQuery = &m_lastQuery; + data.pMultipleResultUpdateCount = &m_multipleResultUpdateCount; + data.pMultipleResultAvailable = &m_multipleResultAvailable; + data.pLastTableInserted = &m_lastTableInserted; + data.pLastResultset = &m_lastResultset; + data.owner = *this; + data.tableSupplier = Reference< com::sun::star::sdbcx::XTablesSupplier >( m_connection, UNO_QUERY ); + data.concurrency = + extractIntProperty( this, getStatics().RESULT_SET_CONCURRENCY ); + return executePostgresCommand( cmd , &data ); +} + +Reference< XConnection > Statement::getConnection( ) + throw (SQLException, RuntimeException) +{ + Reference< XConnection > ret; + { + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + ret = m_connection; + } + return ret; +} + + +Any Statement::getWarnings( ) + throw (SQLException,RuntimeException) +{ + return Any(); +} + +void Statement::clearWarnings( ) + throw (SQLException, RuntimeException) +{ +} + +Reference< ::com::sun::star::sdbc::XResultSetMetaData > Statement::getMetaData() + throw (SQLException,RuntimeException) +{ + Reference< com::sun::star::sdbc::XResultSetMetaData > ret; + Reference< com::sun::star::sdbc::XResultSetMetaDataSupplier > supplier( m_lastResultset, UNO_QUERY ); + if( supplier.is() ) + ret = supplier->getMetaData(); + return ret; +} + + +::cppu::IPropertyArrayHelper & Statement::getInfoHelper() +{ + return getStatementPropertyArrayHelper(); +} + + +sal_Bool Statement::convertFastPropertyValue( + Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) + throw (IllegalArgumentException) +{ + rOldValue = m_props[nHandle]; + sal_Bool bRet; + switch( nHandle ) + { + case STATEMENT_CURSOR_NAME: + { + OUString val; + bRet = ( rValue >>= val ); + rConvertedValue = makeAny( val ); + break; + } + case STATEMENT_ESCAPE_PROCESSING: + { + sal_Bool val; + bRet = ( rValue >>= val ); + rConvertedValue = makeAny( val ); + break; + } + case STATEMENT_FETCH_DIRECTION: + case STATEMENT_FETCH_SIZE: + case STATEMENT_MAX_FIELD_SIZE: + case STATEMENT_MAX_ROWS: + case STATEMENT_QUERY_TIME_OUT: + case STATEMENT_RESULT_SET_CONCURRENCY: + case STATEMENT_RESULT_SET_TYPE: + { + sal_Int32 val; + bRet = ( rValue >>= val ); + rConvertedValue = makeAny( val ); + break; + } + default: + { + OUStringBuffer buf(128); + buf.appendAscii( "pq_statement: Invalid property handle (" ); + buf.append( nHandle ); + buf.appendAscii( ")" ); + throw IllegalArgumentException( buf.makeStringAndClear(), *this, 2 ); + } + } + return bRet; +} + + +void Statement::setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle,const Any& rValue ) throw (Exception) +{ + m_props[nHandle] = rValue; +} + +void Statement::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const +{ + rValue = m_props[nHandle]; +} + +Reference < XPropertySetInfo > Statement::getPropertySetInfo() + throw(RuntimeException) +{ + return OPropertySetHelper::createPropertySetInfo( getStatementPropertyArrayHelper() ); +} + + +Reference< XResultSet > Statement::getResultSet( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return Reference< XResultSet > ( m_lastResultset, com::sun::star::uno::UNO_QUERY ); +} + +sal_Int32 Statement::getUpdateCount( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return m_multipleResultUpdateCount; +} + +sal_Bool Statement::getMoreResults( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + + + +void Statement::disposing() +{ + close(); +} + +Reference< XResultSet > Statement::getGeneratedValues( ) + throw (SQLException, RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + return getGeneratedValuesFromLastInsert( + m_pSettings, m_connection, m_lastOidInserted, m_lastTableInserted, m_lastQuery ); +} + +} diff --git connectivity/source/drivers/postgresql/pq_statement.hxx connectivity/source/drivers/postgresql/pq_statement.hxx new file mode 100644 index 0000000..ba64ac5 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_statement.hxx @@ -0,0 +1,229 @@ +/************************************************************************* + * + * $RCSfile: pq_statement.hxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2006/01/22 15:14:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#ifndef _PQ_STATEMENT_HXX_ +#define _PQ_STATEMENT_HXX_ +#include +#include + +#include + +#include "pq_connection.hxx" +#include +#include +#include + +namespace pq_sdbc_driver +{ + +static const sal_Int32 STATEMENT_CURSOR_NAME = 0; +static const sal_Int32 STATEMENT_ESCAPE_PROCESSING = 1; +static const sal_Int32 STATEMENT_FETCH_DIRECTION = 2; +static const sal_Int32 STATEMENT_FETCH_SIZE = 3; +static const sal_Int32 STATEMENT_MAX_FIELD_SIZE = 4; +static const sal_Int32 STATEMENT_MAX_ROWS = 5; +static const sal_Int32 STATEMENT_QUERY_TIME_OUT = 6; +static const sal_Int32 STATEMENT_RESULT_SET_CONCURRENCY = 7; +static const sal_Int32 STATEMENT_RESULT_SET_TYPE = 8; + +#define STATEMENT_SIZE 9 +class ResultSet; + +class Statement : public cppu::OComponentHelper, + public cppu::OPropertySetHelper, + public com::sun::star::sdbc::XStatement, + public com::sun::star::sdbc::XCloseable, + public com::sun::star::sdbc::XWarningsSupplier, + public com::sun::star::sdbc::XMultipleResults, + public com::sun::star::sdbc::XGeneratedResultSet, + public com::sun::star::sdbc::XResultSetMetaDataSupplier +{ +private: + com::sun::star::uno::Any m_props[STATEMENT_SIZE]; + com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > m_connection; + ConnectionSettings *m_pSettings; + com::sun::star::uno::Reference< com::sun::star::sdbc::XCloseable > m_lastResultset; + ::rtl::Reference< RefCountedMutex > m_refMutex; + sal_Bool m_multipleResultAvailable; + sal_Int32 m_multipleResultUpdateCount; + sal_Int32 m_lastOidInserted; + rtl::OUString m_lastTableInserted; + rtl::OString m_lastQuery; + +public: + /** + * @param ppConnection The piece of memory, pConnection points to, is accessisble + * as long as a reference to paramenter con is held. + */ + Statement( const rtl::Reference< RefCountedMutex > & refMutex, + const com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection> & con, + struct ConnectionSettings *pSettings ); + + virtual ~Statement(); +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XCloseable + virtual void SAL_CALL close( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XStatement + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL executeQuery( + const ::rtl::OUString& sql ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL executeUpdate( const ::rtl::OUString& sql ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL execute( const ::rtl::OUString& sql ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL getConnection( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XWarningsSupplier + virtual ::com::sun::star::uno::Any SAL_CALL getWarnings( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearWarnings( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // OPropertySetHelper + virtual cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper(); + + virtual sal_Bool SAL_CALL convertFastPropertyValue( + ::com::sun::star::uno::Any & rConvertedValue, + ::com::sun::star::uno::Any & rOldValue, + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::lang::IllegalArgumentException); + + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::uno::Exception); + + virtual void SAL_CALL getFastPropertyValue( + ::com::sun::star::uno::Any& rValue, + sal_Int32 nHandle ) const; + + // XPropertySet + ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw(com::sun::star::uno::RuntimeException); + +public: // XGeneratedResultSet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL + getGeneratedValues( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XMultipleResults + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL getResultSet( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getUpdateCount( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL getMoreResults( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // OComponentHelper + virtual void SAL_CALL disposing(); + +public: // XResultSetMetaDataSupplier (is required by framework (see + // dbaccess/source/core/api/preparedstatement.cxx::getMetaData() ) + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL getMetaData( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +private: + void checkClosed() throw (com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException); + void raiseSQLException( const ::rtl::OUString & sql, const char * errorMsg, const char *errorType = 0 ) + throw ( com::sun::star::sdbc::SQLException ); +}; + + +struct CommandData +{ + ConnectionSettings **ppSettings; + sal_Int32 *pLastOidInserted; + sal_Int32 *pMultipleResultUpdateCount; + sal_Bool *pMultipleResultAvailable; + ::rtl::OUString *pLastTableInserted; + ::com::sun::star::uno::Reference< com::sun::star::sdbc::XCloseable > *pLastResultset; + ::rtl::OString *pLastQuery; + ::rtl::Reference< RefCountedMutex > refMutex; + ::com::sun::star::uno::Reference< com::sun::star::uno::XInterface > owner; + ::com::sun::star::uno::Reference< com::sun::star::sdbcx::XTablesSupplier > tableSupplier; + sal_Int32 concurrency; +}; + +bool executePostgresCommand( const rtl::OString & cmd, struct CommandData *data ); +com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet > getGeneratedValuesFromLastInsert( + ConnectionSettings *pConnectionSettings, + const com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > &connection, + sal_Int32 nLastOid, + const rtl::OUString & lastTableInserted, + const rtl::OString & lastQuery ); + + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_statics.cxx connectivity/source/drivers/postgresql/pq_statics.cxx new file mode 100644 index 0000000..177571d --- /dev/null +++ connectivity/source/drivers/postgresql/pq_statics.cxx @@ -0,0 +1,758 @@ +/************************************************************************* + * + * $RCSfile: pq_statics.cxx,v $ + * + * $Revision: 1.1.2.6 $ + * + * last change: $Author: jbu $ $Date: 2007/02/15 20:04:48 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include "pq_statics.hxx" +#include "pq_updateableresultset.hxx" +#include +#include + +using rtl::OUString; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Any; +using com::sun::star::uno::Type; + +using com::sun::star::beans::PropertyAttribute::READONLY; +using com::sun::star::beans::PropertyAttribute::BOUND; +using com::sun::star::beans::Property; + +namespace pq_sdbc_driver +{ + +struct DefColumnMetaData +{ + sal_Char * columnName; + sal_Char * tableName; + sal_Char * schemaTableName; + sal_Char * typeName; + sal_Int32 type; + sal_Int32 precision; + sal_Int32 scale; + sal_Bool isCurrency; + sal_Bool isNullable; + sal_Bool isAutoIncrement; + sal_Bool isReadOnly; + sal_Bool isSigned; +}; + +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) +struct BaseTypeDef { const char * typeName; sal_Int32 value; }; + +static Sequence< OUString > createStringSequence( const char * name[] ) +{ + int length; + for( length = 0; name[length] ; length ++ ); + + Sequence< OUString > seq( length ); + for( int i = 0; i < length; i ++ ) + { + seq[i] = OUString( name[i] , strlen( name[i] ), RTL_TEXTENCODING_ASCII_US ); + } + return seq; +} + +static Sequence< sal_Int8 > generateImplementationId() +{ + Sequence< sal_Int8 > seq( 16 ); + rtl_createUuid( (sal_uInt8*)seq.getArray(), 0 , sal_False ); + return seq; +} + +struct PropertyDef +{ + PropertyDef( const OUString &str, const Type &t ) + : name( str ) , type( t ) {} + ::rtl::OUString name; + com::sun::star::uno::Type type; +}; + +struct PropertyDefEx : public PropertyDef +{ + PropertyDefEx( const OUString & str, const Type &t , sal_Int32 a ) + : PropertyDef( str, t ) , attribute( a ) + {} + sal_Int32 attribute; +}; + +static cppu::IPropertyArrayHelper * createPropertyArrayHelper( + PropertyDef *props, int count , sal_Int16 attr ) +{ + Sequence< Property > seq( count ); + for( int i = 0 ; i < count ; i ++ ) + { + seq[i] = Property( props[i].name, i, props[i].type, attr ); + } + return new cppu::OPropertyArrayHelper( seq, sal_True ); +} + +static cppu::IPropertyArrayHelper * createPropertyArrayHelper( + PropertyDefEx *props, int count ) +{ + Sequence< Property > seq( count ); + for( int i = 0 ; i < count ; i ++ ) + { + seq[i] = Property( props[i].name, i, props[i].type, props[i].attribute ); + } + return new cppu::OPropertyArrayHelper( seq, sal_True ); +} + +Statics & getStatics() +{ + static Statics * p; + if( ! p ) + { + ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); + if( ! p ) + { + static Statics statics ; + statics.SYSTEM_TABLE = ASCII_STR( "SYSTEM TABLE" ); + statics.TABLE = ASCII_STR( "TABLE" ); + statics.VIEW = ASCII_STR( "VIEW" ); + statics.UNKNOWN = ASCII_STR( "UNKNOWN" ); + statics.YES = ASCII_STR( "YES" ); + statics.NO = ASCII_STR( "NO" ); + statics.NO_NULLS = ASCII_STR( "NO_NULLS" ); + statics.NULABLE = ASCII_STR( "NULABLE" ); + statics.NULLABLE_UNKNOWN = ASCII_STR( "NULLABLE_UNKNOWN" ); + statics.cPERCENT = ASCII_STR( "%" ); + + statics.TYPE = ASCII_STR( "Type" ); + statics.TYPE_NAME = ASCII_STR( "TypeName" ); + statics.NAME = ASCII_STR( "Name" ); + statics.SCHEMA_NAME = ASCII_STR( "SchemaName" ); + statics.CATALOG_NAME = ASCII_STR( "CatalogName" ); + statics.DESCRIPTION = ASCII_STR( "Description" ); + statics.PRIVILEGES = ASCII_STR( "Privileges" ); + + statics.DEFAULT_VALUE = ASCII_STR( "DefaultValue" ); + statics.IS_AUTO_INCREMENT = ASCII_STR( "IsAutoIncrement" ); + statics.IS_CURRENCY = ASCII_STR( "IsCurrency" ); + statics.IS_NULLABLE = ASCII_STR( "IsNullable" ); + statics.IS_ROW_VERSISON = ASCII_STR( "IsRowVersion" ); + statics.PRECISION = ASCII_STR( "Precision" ); + statics.SCALE = ASCII_STR( "Scale" ); + + statics.cPERCENT = ASCII_STR( "%" ); + statics.BEGIN = ASCII_STR( "BEGIN" ); + statics.COMMIT = ASCII_STR( "COMMIT" ); + statics.ROLLBACK = ASCII_STR( "ROLLBACK" ); + + statics.KEY = ASCII_STR( "Key" ); + statics.REFERENCED_TABLE = ASCII_STR( "ReferencedTable" ); + statics.UPDATE_RULE = ASCII_STR( "UpdateRule" ); + statics.DELETE_RULE = ASCII_STR( "DeleteRule" ); + statics.PRIVATE_COLUMNS = ASCII_STR( "PrivateColumns" ); + statics.PRIVATE_FOREIGN_COLUMNS = ASCII_STR( "PrivateForeignColumns" ); + + statics.KEY_COLUMN = ASCII_STR( "KeyColumn" ); + statics.RELATED_COLUMN = ASCII_STR( "RelatedColumn" ); + statics.PASSWORD = ASCII_STR( "Password" ); + statics.USER = ASCII_STR( "User" ); + + statics.CURSOR_NAME = ASCII_STR( "CursorName" ); + statics.ESCAPE_PROCESSING = ASCII_STR( "EscapeProcessing" ); + statics.FETCH_DIRECTION = ASCII_STR( "FetchDirection" ); + statics.FETCH_SIZE = ASCII_STR( "FetchSize" ); + statics.IS_BOOKMARKABLE = ASCII_STR( "IsBookmarkable" ); + statics.RESULT_SET_CONCURRENCY = ASCII_STR( "ResultSetConcurrency" ); + statics.RESULT_SET_TYPE = ASCII_STR( "ResultSetType" ); + + statics.COMMAND = ASCII_STR( "Command" ); + statics.CHECK_OPTION = ASCII_STR( "CheckOption" ); + + statics.TRUE = ASCII_STR( "t" ); + statics.FALSE = ASCII_STR( "f" ); + statics.IS_PRIMARY_KEY_INDEX = ASCII_STR( "IsPrimaryKeyIndex" ); + statics.IS_CLUSTERED = ASCII_STR( "IsClustered" ); + statics.IS_UNIQUE = ASCII_STR( "IsUnique" ); + statics.IS_ASCENDING = ASCII_STR( "IsAscending" ); + statics.PRIVATE_COLUMN_INDEXES = ASCII_STR( "PrivateColumnIndexes" ); + statics.HELP_TEXT = ASCII_STR( "HelpText" ); + + statics.CATALOG = ASCII_STR( "Catalog" ); + + Type tString = getCppuType( (rtl::OUString *) 0 ); + Type tInt = getCppuType( (sal_Int32 * ) 0 ); + Type tBool = getBooleanCppuType(); + Type tStringSequence = getCppuType( (com::sun::star::uno::Sequence< ::rtl::OUString > *) 0); + + // Table props set + ImplementationStatics &ist = statics.refl.table; + ist.implName = ASCII_STR( "org.openoffice.comp.pq.sdbcx.Table" ); + ist.serviceNames = Sequence< OUString > ( 1 ); + ist.serviceNames[0] = ASCII_STR( "com.sun.star.sdbcx.Table" ); + PropertyDef tableDef[] = + { + PropertyDef( statics.CATALOG_NAME , tString ), + PropertyDef( statics.DESCRIPTION , tString ), + PropertyDef( statics.NAME , tString ), + PropertyDef( statics.PRIVILEGES , tInt ), + PropertyDef( statics.SCHEMA_NAME , tString ), + PropertyDef( statics.TYPE , tString ) + }; + ist.pProps = createPropertyArrayHelper( + tableDef, sizeof(tableDef)/sizeof(PropertyDef), READONLY ); + + statics.refl.tableDescriptor.implName = + ASCII_STR( "org.openoffice.comp.pq.sdbcx.TableDescriptor" ); + statics.refl.tableDescriptor.serviceNames = Sequence< OUString > (1); + statics.refl.tableDescriptor.serviceNames[0] = + ASCII_STR( "com.sun.star.sdbcx.TableDescriptor" ); + PropertyDef tableDescDef[] = + { + PropertyDef( statics.CATALOG_NAME , tString ), + PropertyDef( statics.DESCRIPTION , tString ), + PropertyDef( statics.NAME , tString ), + PropertyDef( statics.PRIVILEGES , tInt ), + PropertyDef( statics.SCHEMA_NAME , tString ) + }; + statics.refl.tableDescriptor.pProps = createPropertyArrayHelper( + tableDescDef, sizeof(tableDescDef)/sizeof(PropertyDef), 0 ); + + // Column props set + statics.refl.column.implName = ASCII_STR( "org.openoffice.comp.pq.sdbcx.Column" ); + statics.refl.column.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.column.serviceNames[0] = ASCII_STR( "com.sun.star.sdbcx.Column" ); + PropertyDefEx columnDef[] = + { + PropertyDefEx( statics.CATALOG_NAME , tString, READONLY ), + PropertyDefEx( statics.DEFAULT_VALUE, tString, READONLY ), + PropertyDefEx( statics.DESCRIPTION , tString, READONLY ), +// PropertyDefEx( statics.HELP_TEXT , tString, BOUND ), + PropertyDefEx( statics.IS_AUTO_INCREMENT, tBool, READONLY ), + PropertyDefEx( statics.IS_CURRENCY, tBool, READONLY ), + PropertyDefEx( statics.IS_NULLABLE, tInt, READONLY ), + PropertyDefEx( statics.IS_ROW_VERSISON, tBool,READONLY ), + PropertyDefEx( statics.NAME , tString,READONLY ), + PropertyDefEx( statics.PRECISION , tInt, READONLY ), + PropertyDefEx( statics.SCALE , tInt ,READONLY), + PropertyDefEx( statics.TYPE , tInt ,READONLY), + PropertyDefEx( statics.TYPE_NAME , tString ,READONLY) + }; + statics.refl.column.pProps = createPropertyArrayHelper( + columnDef, sizeof(columnDef)/sizeof(PropertyDefEx) ); + + statics.refl.columnDescriptor.implName = + ASCII_STR( "org.openoffice.comp.pq.sdbcx.ColumnDescriptor" ); + statics.refl.columnDescriptor.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.columnDescriptor.serviceNames[0] = + ASCII_STR( "com.sun.star.sdbcx.ColumnDescriptor" ); + PropertyDef columnDescDef[] = + { + PropertyDef( statics.CATALOG_NAME , tString ), + PropertyDef( statics.DEFAULT_VALUE, tString ), + PropertyDef( statics.DESCRIPTION , tString ), +// PropertyDef( statics.HELP_TEXT , tString ), + PropertyDef( statics.IS_AUTO_INCREMENT, tBool ), + PropertyDef( statics.IS_CURRENCY, tBool ), + PropertyDef( statics.IS_NULLABLE, tInt ), + PropertyDef( statics.IS_ROW_VERSISON, tBool ), + PropertyDef( statics.NAME , tString ), + PropertyDef( statics.PRECISION , tInt ), + PropertyDef( statics.SCALE , tInt ), + PropertyDef( statics.TYPE , tInt ), + PropertyDef( statics.TYPE_NAME , tString ) + }; + + statics.refl.columnDescriptor.pProps = createPropertyArrayHelper( + columnDescDef, sizeof(columnDescDef)/sizeof(PropertyDef), 0 ); + + // Key properties + statics.refl.key.implName = ASCII_STR( "org.openoffice.comp.pq.sdbcx.Key" ); + statics.refl.key.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.key.serviceNames[0] = ASCII_STR( "com.sun.star.sdbcx.Key" ); + PropertyDef keyDef[] = + { + PropertyDef( statics.DELETE_RULE, tInt ), + PropertyDef( statics.NAME, tString ), + PropertyDef( statics.PRIVATE_COLUMNS, tStringSequence ), + PropertyDef( statics.PRIVATE_FOREIGN_COLUMNS, tStringSequence ), + PropertyDef( statics.REFERENCED_TABLE, tString ), + PropertyDef( statics.TYPE, tInt ), + PropertyDef( statics.UPDATE_RULE, tInt ) + }; + statics.refl.key.pProps = createPropertyArrayHelper( + keyDef, sizeof(keyDef)/sizeof(PropertyDef), READONLY ); + + + // Key properties + statics.refl.keyDescriptor.implName = + ASCII_STR( "org.openoffice.comp.pq.sdbcx.KeyDescriptor" ); + statics.refl.keyDescriptor.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.keyDescriptor.serviceNames[0] = + ASCII_STR( "com.sun.star.sdbcx.KeyDescriptor" ); + PropertyDef keyDescDef[] = + { + PropertyDef( statics.DELETE_RULE, tInt ), + PropertyDef( statics.NAME, tString ), + PropertyDef( statics.REFERENCED_TABLE, tString ), + PropertyDef( statics.TYPE, tInt ), + PropertyDef( statics.UPDATE_RULE, tInt ) + }; + statics.refl.keyDescriptor.pProps = createPropertyArrayHelper( + keyDescDef, sizeof(keyDescDef)/sizeof(PropertyDef), 0 ); + + + + // KeyColumn props set + statics.refl.keycolumn.implName = ASCII_STR( "org.openoffice.comp.pq.sdbcx.KeyColumn" ); + statics.refl.keycolumn.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.keycolumn.serviceNames[0] = ASCII_STR( "com.sun.star.sdbcx.KeyColumn" ); + PropertyDef keycolumnDef[] = + { + PropertyDef( statics.CATALOG_NAME , tString ), + PropertyDef( statics.DEFAULT_VALUE, tString ), + PropertyDef( statics.DESCRIPTION , tString ), + PropertyDef( statics.IS_AUTO_INCREMENT, tBool ), + PropertyDef( statics.IS_CURRENCY, tBool ), + PropertyDef( statics.IS_NULLABLE, tInt ), + PropertyDef( statics.IS_ROW_VERSISON, tBool ), + PropertyDef( statics.NAME , tString ), + PropertyDef( statics.PRECISION , tInt ), + PropertyDef( statics.RELATED_COLUMN, tString ), + PropertyDef( statics.SCALE , tInt ), + PropertyDef( statics.TYPE , tInt ), + PropertyDef( statics.TYPE_NAME , tString ) + }; + statics.refl.keycolumn.pProps = createPropertyArrayHelper( + keycolumnDef, sizeof(keycolumnDef)/sizeof(PropertyDef), READONLY ); + + // KeyColumn props set + statics.refl.keycolumnDescriptor.implName = + ASCII_STR( "org.openoffice.comp.pq.sdbcx.KeyColumnDescriptor" ); + statics.refl.keycolumnDescriptor.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.keycolumnDescriptor.serviceNames[0] = + ASCII_STR( "com.sun.star.sdbcx.KeyColumnDescriptor" ); + PropertyDef keycolumnDescDef[] = + { + PropertyDef( statics.NAME , tString ), + PropertyDef( statics.RELATED_COLUMN, tString ) + }; + statics.refl.keycolumnDescriptor.pProps = createPropertyArrayHelper( + keycolumnDescDef, sizeof(keycolumnDescDef)/sizeof(PropertyDef), 0 ); + + // view props set + statics.refl.view.implName = ASCII_STR( "org.openoffice.comp.pq.sdbcx.View"); + statics.refl.view.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.view.serviceNames[0] = ASCII_STR( "com.sun.star.sdbcx.View" ); + PropertyDef viewDef[] = + { + PropertyDef( statics.CATALOG_NAME , tString ), + PropertyDef( statics.CHECK_OPTION , tInt ), + PropertyDef( statics.COMMAND , tString ), + PropertyDef( statics.NAME , tString ), + PropertyDef( statics.SCHEMA_NAME , tString ) + }; + statics.refl.view.pProps = createPropertyArrayHelper( + viewDef, sizeof(viewDef)/sizeof(PropertyDef), READONLY ); + + // view props set + statics.refl.viewDescriptor.implName = ASCII_STR( "org.openoffice.comp.pq.sdbcx.ViewDescriptor"); + statics.refl.viewDescriptor.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.viewDescriptor.serviceNames[0] = ASCII_STR( "com.sun.star.sdbcx.ViewDescriptor" ); + statics.refl.viewDescriptor.pProps = createPropertyArrayHelper( + viewDef, sizeof(viewDef)/sizeof(PropertyDef), 0 ); // reuse view, as it is identical + // user props set + statics.refl.user.implName = ASCII_STR( "org.openoffice.comp.pq.sdbcx.User"); + statics.refl.user.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.user.serviceNames[0] = ASCII_STR( "com.sun.star.sdbcx.User" ); + PropertyDef userDefRO[] = + { + PropertyDef( statics.NAME , tString ) + }; + statics.refl.user.pProps = createPropertyArrayHelper( + userDefRO, sizeof(userDefRO)/sizeof(PropertyDef), READONLY ); + + // user props set + statics.refl.userDescriptor.implName = + ASCII_STR( "org.openoffice.comp.pq.sdbcx.UserDescriptor"); + statics.refl.userDescriptor.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.userDescriptor.serviceNames[0] = + ASCII_STR( "com.sun.star.sdbcx.UserDescriptor" ); + PropertyDef userDefWR[] = + { + PropertyDef( statics.NAME , tString ), + PropertyDef( statics.PASSWORD , tString ) + }; + statics.refl.userDescriptor.pProps = createPropertyArrayHelper( + userDefWR, sizeof(userDefWR)/sizeof(PropertyDef), 0 ); + + // index props set + statics.refl.index.implName = ASCII_STR( "org.openoffice.comp.pq.sdbcx.Index"); + statics.refl.index.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.index.serviceNames[0] = ASCII_STR( "com.sun.star.sdbcx.Index" ); + PropertyDef indexDef[] = + { + PropertyDef( statics.CATALOG , tString ), + PropertyDef( statics.IS_CLUSTERED, tBool ), + PropertyDef( statics.IS_PRIMARY_KEY_INDEX, tBool ), + PropertyDef( statics.IS_UNIQUE, tBool ), + PropertyDef( statics.NAME , tString ), + PropertyDef( statics.PRIVATE_COLUMN_INDEXES, tStringSequence ) + }; + statics.refl.index.pProps = createPropertyArrayHelper( + indexDef, sizeof(indexDef)/sizeof(PropertyDef), READONLY ); + + // index props set + statics.refl.indexDescriptor.implName = + ASCII_STR( "org.openoffice.comp.pq.sdbcx.IndexDescriptor"); + statics.refl.indexDescriptor.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.indexDescriptor.serviceNames[0] = + ASCII_STR( "com.sun.star.sdbcx.IndexDescriptor" ); + statics.refl.indexDescriptor.pProps = createPropertyArrayHelper( + indexDef, sizeof(indexDef)/sizeof(PropertyDef), 0 ); + + // indexColumn props set + statics.refl.indexColumn.implName = ASCII_STR( "org.openoffice.comp.pq.sdbcx.IndexColumn"); + statics.refl.indexColumn.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.indexColumn.serviceNames[0] = ASCII_STR("com.sun.star.sdbcx.IndexColumn"); + PropertyDef indexColumnDef[] = + { + PropertyDef( statics.CATALOG_NAME , tString ), + PropertyDef( statics.DEFAULT_VALUE, tString ), + PropertyDef( statics.DESCRIPTION , tString ), + PropertyDef( statics.IS_ASCENDING, tBool ), + PropertyDef( statics.IS_AUTO_INCREMENT, tBool ), + PropertyDef( statics.IS_CURRENCY, tBool ), + PropertyDef( statics.IS_NULLABLE, tInt ), + PropertyDef( statics.IS_ROW_VERSISON, tBool ), + PropertyDef( statics.NAME , tString ), + PropertyDef( statics.PRECISION , tInt ), + PropertyDef( statics.SCALE , tInt ), + PropertyDef( statics.TYPE , tInt ), + PropertyDef( statics.TYPE_NAME , tString ) + }; + statics.refl.indexColumn.pProps = createPropertyArrayHelper( + indexColumnDef, sizeof(indexColumnDef)/sizeof(PropertyDef), READONLY ); + + // indexColumn props set + statics.refl.indexColumnDescriptor.implName = + ASCII_STR( "org.openoffice.comp.pq.sdbcx.IndexColumnDescriptor"); + statics.refl.indexColumnDescriptor.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.indexColumnDescriptor.serviceNames[0] = + ASCII_STR("com.sun.star.sdbcx.IndexColumnDescriptor"); + PropertyDef indexColumnDescDef[] = + { + PropertyDef( statics.IS_ASCENDING, tBool ), + PropertyDef( statics.NAME , tString ) + }; + statics.refl.indexColumnDescriptor.pProps = createPropertyArrayHelper( + indexColumnDescDef, sizeof(indexColumnDescDef)/sizeof(PropertyDef), 0 ); + + // resultset + statics.refl.resultSet.implName = ASCII_STR( "org.openoffice.comp.pq.ResultSet"); + statics.refl.resultSet.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.resultSet.serviceNames[0] = ASCII_STR( "com.sun.star.sdbc.ResultSet" ); + statics.refl.resultSet.types = UpdateableResultSet::getStaticTypes( false /* updateable */ ); + PropertyDef resultSet[] = + { + PropertyDef( statics.CURSOR_NAME , tString ), + PropertyDef( statics.ESCAPE_PROCESSING , tBool ), + PropertyDef( statics.FETCH_DIRECTION , tInt ), + PropertyDef( statics.FETCH_SIZE , tInt ), + PropertyDef( statics.IS_BOOKMARKABLE , tBool ), + PropertyDef( statics.RESULT_SET_CONCURRENCY , tInt ), + PropertyDef( statics.RESULT_SET_TYPE , tInt ) + }; + statics.refl.resultSet.pProps = createPropertyArrayHelper( + resultSet, sizeof(resultSet)/sizeof(PropertyDef), 0 ); + + // updateableResultset + statics.refl.updateableResultSet.implName = ASCII_STR( "org.openoffice.comp.pq.UpdateableResultSet"); + statics.refl.updateableResultSet.serviceNames = Sequence< OUString > ( 1 ); + statics.refl.updateableResultSet.serviceNames[0] = ASCII_STR( "com.sun.star.sdbc.ResultSet" ); + statics.refl.updateableResultSet.types = UpdateableResultSet::getStaticTypes( true /* updateable */ ); + statics.refl.updateableResultSet.pProps = createPropertyArrayHelper( + resultSet, sizeof(resultSet)/sizeof(PropertyDef), 0 ); + + // databasemetadata + statics.tablesRowNames = Sequence< OUString > ( 5 ); + statics.tablesRowNames[TABLE_INDEX_CATALOG] = ASCII_STR( "TABLE_CAT" ); + statics.tablesRowNames[TABLE_INDEX_SCHEMA] = ASCII_STR( "TABLE_SCHEM" ); + statics.tablesRowNames[TABLE_INDEX_NAME] = ASCII_STR( "TABLE_NAME" ); + statics.tablesRowNames[TABLE_INDEX_TYPE] = ASCII_STR( "TABLE_TYPE" ); + statics.tablesRowNames[TABLE_INDEX_REMARKS] = ASCII_STR( "REMARKS" ); + + statics.primaryKeyNames = Sequence< OUString > ( 6 ); + statics.primaryKeyNames[0] = ASCII_STR( "TABLE_CAT" ); + statics.primaryKeyNames[1] = ASCII_STR( "TABLE_SCHEM" ); + statics.primaryKeyNames[2] = ASCII_STR( "TABLE_NAME" ); + statics.primaryKeyNames[3] = ASCII_STR( "COLUMN_NAME" ); + statics.primaryKeyNames[4] = ASCII_STR( "KEY_SEQ" ); + statics.primaryKeyNames[5] = ASCII_STR( "PK_NAME" ); + + statics.SELECT = ASCII_STR( "SELECT" ); + statics.UPDATE = ASCII_STR( "UPDATE" ); + statics.INSERT = ASCII_STR( "INSERT" ); + statics.DELETE = ASCII_STR( "DELETE" ); + statics.RULE = ASCII_STR( "RULE" ); + statics.REFERENCES = ASCII_STR( "REFERENCES" ); + statics.TRIGGER = ASCII_STR( "TRIGGER" ); + statics.EXECUTE = ASCII_STR( "EXECUTE" ); + statics.USAGE = ASCII_STR( "USAGE" ); + statics.CREATE = ASCII_STR( "CREATE" ); + statics.TEMPORARY = ASCII_STR( "TEMPORARY" ); + statics.INDEX = ASCII_STR( "Index" ); + statics.INDEX_COLUMN = ASCII_STR( "IndexColumn" ); + + statics.schemaNames = Sequence< OUString > ( 1 ); + statics.schemaNames[0] = ASCII_STR( "TABLE_SCHEM" ); + + statics.tableTypeData = Sequence< Sequence< Any > >( 2 ); + + statics.tableTypeData[0] = Sequence< Any > ( 1 ); + statics.tableTypeData[0][0] <<= statics.TABLE; + +// statics.tableTypeData[2] = Sequence< Any > ( 1 ); +// statics.tableTypeData[2][0] <<= statics.VIEW; + + statics.tableTypeData[1] = Sequence< Any > ( 1 ); + statics.tableTypeData[1][0] <<= statics.SYSTEM_TABLE; + + statics.tableTypeNames = Sequence< OUString > ( 1 ); + statics.tableTypeNames[0] = ASCII_STR( "TABLE_TYPE" ); + + static const char *tablePrivilegesNames[] = + { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "GRANTOR", "GRANTEE", "PRIVILEGE", + "IS_GRANTABLE" , 0 + }; + statics.tablePrivilegesNames = + createStringSequence( tablePrivilegesNames ); + + static const char * columnNames[] = + { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", + "DATA_TYPE", "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", + "DECIMAL_DIGITS", "NUM_PREC_RADIX", "NULLABLE", "REMARKS", + "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", + "ORDINAL_POSITION", "IS_NULLABLE", 0 + }; + statics.columnRowNames = + createStringSequence( columnNames ); + + static const char * typeinfoColumnNames[] = + { + "TYPE_NAME", "DATA_TYPE", "PRECISION", "LITERAL_PREFIX", + "LITERAL_SUFFIX", "CREATE_PARAMS", "NULLABLE", "CASE_SENSITIVE", + "SEARCHABLE", "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", + "AUTO_INCREMENT", "LOCAL_TYPE_NAME", "MINIMUM_SCALE", + "MAXIMUM_SCALE", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", + "NUM_PREC_RADIX", 0 + }; + statics.typeinfoColumnNames = createStringSequence( typeinfoColumnNames ); + + static const char * indexinfoColumnNames[] = + { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "NON_UNIQUE", "INDEX_QUALIFIER", "INDEX_NAME", + "TYPE", "ORDINAL_POSITION", "COLUMN_NAME", + "ASC_OR_DESC", "CARDINALITY", "PAGES", "FILTER_CONDITION",0 + }; + statics.indexinfoColumnNames = createStringSequence( indexinfoColumnNames ); + + static const char * importedKeysColumnNames[] = + { + "PKTABLE_CAT" , + "PKTABLE_SCHEM", + "PKTABLE_NAME" , + "PKCOLUMN_NAME", + "FKTABLE_CAT" , + "FKTABLE_SCHEM", + "FKTABLE_NAME" , + "FKCOLUMN_NAME", + "KEY_SEQ" , + "UPDATE_RULE", + "DELETE_RULE", + "FK_NAME" , + "PK_NAME" , + "DEFERRABILITY" , + 0 + }; + statics.importedKeysColumnNames = + createStringSequence( importedKeysColumnNames ); + + static const char * resultSetArrayColumnNames[] = { "INDEX" , "VALUE", 0 }; + statics.resultSetArrayColumnNames = + createStringSequence( resultSetArrayColumnNames ); + + BaseTypeDef baseTypeDefs[] = + { + { "bool" , com::sun::star::sdbc::DataType::BIT }, + { "bytea", com::sun::star::sdbc::DataType::VARBINARY }, + { "char" , com::sun::star::sdbc::DataType::CHAR }, + + { "int8" , com::sun::star::sdbc::DataType::BIGINT }, + { "serial8" , com::sun::star::sdbc::DataType::BIGINT }, + + + { "int2" , com::sun::star::sdbc::DataType::SMALLINT }, + + { "int4" , com::sun::star::sdbc::DataType::INTEGER }, +// { "regproc" , com::sun::star::sdbc::DataType::INTEGER }, +// { "oid" , com::sun::star::sdbc::DataType::INTEGER }, +// { "xid" , com::sun::star::sdbc::DataType::INTEGER }, +// { "cid" , com::sun::star::sdbc::DataType::INTEGER }, +// { "serial", com::sun::star::sdbc::DataType::INTEGER }, +// { "serial4", com::sun::star::sdbc::DataType::INTEGER }, + + { "text", com::sun::star::sdbc::DataType::VARCHAR }, + { "bpchar", com::sun::star::sdbc::DataType::CHAR }, + { "varchar", com::sun::star::sdbc::DataType::VARCHAR }, + + { "float4", com::sun::star::sdbc::DataType::REAL }, + { "float8", com::sun::star::sdbc::DataType::DOUBLE }, + + { "numeric", com::sun::star::sdbc::DataType::NUMERIC }, + { "decimal", com::sun::star::sdbc::DataType::DECIMAL }, + + { "date", com::sun::star::sdbc::DataType::DATE }, // switch to date later + { "time", com::sun::star::sdbc::DataType::TIME }, // switch to time later + { "timestamp", com::sun::star::sdbc::DataType::TIMESTAMP }, // switch to time later + +// { "_bool" , com::sun::star::sdbc::DataType::ARRAY }, +// { "_bytea", com::sun::star::sdbc::DataType::ARRAY }, +// { "_char" , com::sun::star::sdbc::DataType::ARRAY }, + +// { "_int8" , com::sun::star::sdbc::DataType::ARRAY }, +// { "_serial8" , com::sun::star::sdbc::DataType::ARRAY }, + + +// { "_int2" , com::sun::star::sdbc::DataType::ARRAY }, + +// { "_int4" , com::sun::star::sdbc::DataType::ARRAY }, +// { "_regproc" , com::sun::star::sdbc::DataType::ARRAY }, +// { "_oid" , com::sun::star::sdbc::DataType::ARRAY }, +// { "_xid" , com::sun::star::sdbc::DataType::ARRAY }, +// { "_cid" , com::sun::star::sdbc::DataType::ARRAY }, + +// { "_text", com::sun::star::sdbc::DataType::ARRAY }, +// { "_bpchar", com::sun::star::sdbc::DataType::ARRAY }, +// { "_varchar", com::sun::star::sdbc::DataType::ARRAY }, + +// { "_float4", com::sun::star::sdbc::DataType::ARRAY }, +// { "_float8", com::sun::star::sdbc::DataType::ARRAY }, + +// { "_numeric", com::sun::star::sdbc::DataType::ARRAY }, +// { "_decimal", com::sun::star::sdbc::DataType::ARRAY }, + +// { "_date", com::sun::star::sdbc::DataType::ARRAY }, // switch to date later +// { "_time", com::sun::star::sdbc::DataType::ARRAY }, // switch to time later + + { 0, 0 } + }; + int i; + for( i = 0 ; baseTypeDefs[i].typeName ; i ++ ) + { + statics.baseTypeMap[ + OUString::createFromAscii( baseTypeDefs[i].typeName) ] = + baseTypeDefs[i].value; + } + + DefColumnMetaData defTypeInfoMetaData[] = + { + { "TYPE_NAME", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::VARCHAR, 0,50,0,0,0,0 }, // 0 + { "DATA_TYPE", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 1 + { "PRECISION", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 2 + { "foo1", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 3 + { "foo2", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 4 + { "CREATE_PARAMS", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::VARCHAR, 0,50,0,0,0,0 }, // 5 + { "NULLABLE", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 6 + { "CASE_SENSITIVE", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::BIT, 0,50,0,0,0,0 }, // 7 + { "SEARCHABLE", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::SMALLINT, 0,50,0,0,0,0 }, // 8 + { "UNSIGNED_ATTRIBUTE", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::BIT, 0,50,0,0,0,0 }, // 9 + { "FIXED_PREC_SCALE", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::BIT, 0,50,0,0,0,0 }, // 10 + { "AUTO_INCREMENT", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::BIT, 0,50,0,0,0,0 }, // 11 + { "foo3", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 12 + { "MINIMUM_SCALE", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 13 + { "MAXIMUM_SCALE", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 14 + { "foo4", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 15 + { "foo5", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 16 + { "NUM_PREC_RADIX", "TYPEINFO", "pg_catalog", "", com::sun::star::sdbc::DataType::INTEGER, 0,50,0,0,0,0 }, // 17 + {0,0,0,0,0,0,0,0,0,0,0} + }; + + for( i = 0 ; defTypeInfoMetaData[i].columnName ; i++ ) + { + statics.typeInfoMetaData.push_back( + ColumnMetaData( + rtl::OUString::createFromAscii( defTypeInfoMetaData[i].columnName ), + rtl::OUString::createFromAscii( defTypeInfoMetaData[i].tableName ), + rtl::OUString::createFromAscii( defTypeInfoMetaData[i].schemaTableName ), + rtl::OUString::createFromAscii( defTypeInfoMetaData[i].typeName ), + defTypeInfoMetaData[i].type, + defTypeInfoMetaData[i].precision, + defTypeInfoMetaData[i].scale, + defTypeInfoMetaData[i].isCurrency, + defTypeInfoMetaData[i].isNullable, + defTypeInfoMetaData[i].isAutoIncrement, + defTypeInfoMetaData[i].isReadOnly, + defTypeInfoMetaData[i].isSigned ) ); + } + + p = &statics; + } + } + return *p; +} + + + +} diff --git connectivity/source/drivers/postgresql/pq_statics.hxx connectivity/source/drivers/postgresql/pq_statics.hxx new file mode 100644 index 0000000..5b06a82 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_statics.hxx @@ -0,0 +1,296 @@ +/************************************************************************* + * + * $RCSfile: pq_statics.hxx,v $ + * + * $Revision: 1.1.2.4 $ + * + * last change: $Author: jbu $ $Date: 2006/01/22 15:14:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ +#ifndef _PQ_STATICS_HXX_ +#define _PQ_STATICS_HXX_ + +#include +#include + +#include + +#include +#include +#include + +#include + +#include "pq_allocator.hxx" + +namespace pq_sdbc_driver +{ + +struct ColumnMetaData +{ + ColumnMetaData( + const rtl::OUString &_columnName, + const rtl::OUString &_tableName, + const rtl::OUString &_schemaTableName, + const rtl::OUString &_typeName, + sal_Int32 _type, + sal_Int32 _precision, + sal_Int32 _scale, + sal_Bool _isCurrency, + sal_Bool _isNullable, + sal_Bool _isAutoIncrement, + sal_Bool _isReadOnly, + sal_Bool _isSigned ) : + columnName( _columnName ), + tableName( _tableName ), + schemaTableName( _schemaTableName ), + typeName( _typeName ), + type( _type ), + precision( _precision ), + scale( _scale ), + isCurrency( _isCurrency ), + isNullable( _isNullable ), + isAutoIncrement( _isAutoIncrement ), + isReadOnly( _isReadOnly ), + isSigned( _isSigned ) + {} + + rtl::OUString columnName; + rtl::OUString tableName; + rtl::OUString schemaTableName; + rtl::OUString typeName; + sal_Int32 type; + sal_Int32 precision; + sal_Int32 scale; + sal_Bool isCurrency; + sal_Bool isNullable; + sal_Bool isAutoIncrement; + sal_Bool isReadOnly; + sal_Bool isSigned; +}; + +typedef std::vector< ColumnMetaData, Allocator< ColumnMetaData > > ColumnMetaDataVector; + +struct TypeDetails +{ + sal_Int32 dataType; + sal_Int32 minScale; + sal_Int32 maxScale; // in case nothing is given in getTypeInfo + sal_Bool isAutoIncrement; + sal_Bool isSearchable; +}; + +typedef ::std::hash_map +< + rtl::OUString, + sal_Int32, + rtl::OUStringHash, + ::std::equal_to< rtl::OUString >, + Allocator< ::std::pair< const ::rtl::OUString , sal_Int32 > > +> BaseTypeMap; + + + +struct ImplementationStatics +{ + ImplementationStatics() : + implementationId( 16 ) + { + rtl_createUuid( (sal_uInt8*)implementationId.getArray(), 0 , sal_False ); + } + + rtl::OUString implName; + com::sun::star::uno::Sequence< ::rtl::OUString > serviceNames; + com::sun::star::uno::Sequence< sal_Int8 > implementationId; + cppu::IPropertyArrayHelper *pProps; + com::sun::star::uno::Sequence< com::sun::star::uno::Type > types; +}; + +struct ReflectionImplementations +{ + struct ImplementationStatics table; + struct ImplementationStatics tableDescriptor; + struct ImplementationStatics column; + struct ImplementationStatics columnDescriptor; + struct ImplementationStatics key; + struct ImplementationStatics keyDescriptor; + struct ImplementationStatics keycolumn; + struct ImplementationStatics keycolumnDescriptor; + struct ImplementationStatics user; + struct ImplementationStatics userDescriptor; + struct ImplementationStatics view; + struct ImplementationStatics viewDescriptor; + struct ImplementationStatics index; + struct ImplementationStatics indexDescriptor; + struct ImplementationStatics indexColumn; + struct ImplementationStatics indexColumnDescriptor; + + struct ImplementationStatics updateableResultSet; + struct ImplementationStatics resultSet; +}; + +static const sal_Int32 TABLE_INDEX_CATALOG = 0; +static const sal_Int32 TABLE_INDEX_SCHEMA = 1; +static const sal_Int32 TABLE_INDEX_NAME = 2; +static const sal_Int32 TABLE_INDEX_TYPE = 3; +static const sal_Int32 TABLE_INDEX_REMARKS = 4; + +struct Statics +{ + ::rtl::OUString SYSTEM_TABLE; + ::rtl::OUString TABLE; + ::rtl::OUString VIEW; + ::rtl::OUString UNKNOWN; + ::rtl::OUString YES; + ::rtl::OUString NO; + ::rtl::OUString NO_NULLS; + ::rtl::OUString NULABLE; + ::rtl::OUString NULLABLE_UNKNOWN; + ::rtl::OUString SELECT; + ::rtl::OUString UPDATE; + ::rtl::OUString INSERT; + ::rtl::OUString DELETE; + ::rtl::OUString RULE; + ::rtl::OUString REFERENCES; + ::rtl::OUString TRIGGER; + ::rtl::OUString EXECUTE; + ::rtl::OUString USAGE; + ::rtl::OUString CREATE; + ::rtl::OUString TEMPORARY; + ::rtl::OUString INDEX; + ::rtl::OUString INDEX_COLUMN; + + ::rtl::OUString NAME; + ::rtl::OUString SCHEMA_NAME; + ::rtl::OUString CATALOG_NAME; + ::rtl::OUString DESCRIPTION; + ::rtl::OUString TYPE; + ::rtl::OUString TYPE_NAME; + ::rtl::OUString PRIVILEGES; + + ::rtl::OUString DEFAULT_VALUE; + ::rtl::OUString IS_AUTO_INCREMENT; + ::rtl::OUString IS_CURRENCY; + ::rtl::OUString IS_NULLABLE; + ::rtl::OUString IS_ROW_VERSISON; + ::rtl::OUString PRECISION; + ::rtl::OUString SCALE; + + ::rtl::OUString cPERCENT; + + ::rtl::OUString BEGIN; + ::rtl::OUString ROLLBACK; + ::rtl::OUString COMMIT; + + ::rtl::OUString KEY; + ::rtl::OUString REFERENCED_TABLE; + ::rtl::OUString UPDATE_RULE; + ::rtl::OUString DELETE_RULE; + ::rtl::OUString PRIVATE_COLUMNS; + ::rtl::OUString PRIVATE_FOREIGN_COLUMNS; + + ::rtl::OUString KEY_COLUMN; + ::rtl::OUString RELATED_COLUMN; + + ::rtl::OUString PASSWORD; + ::rtl::OUString USER; + + ::rtl::OUString CURSOR_NAME; + ::rtl::OUString ESCAPE_PROCESSING; + ::rtl::OUString FETCH_DIRECTION; + ::rtl::OUString FETCH_SIZE; + ::rtl::OUString IS_BOOKMARKABLE; + ::rtl::OUString RESULT_SET_CONCURRENCY; + ::rtl::OUString RESULT_SET_TYPE; + + ::rtl::OUString COMMAND; + ::rtl::OUString CHECK_OPTION; + + ::rtl::OUString TRUE; + ::rtl::OUString FALSE; + + ::rtl::OUString IS_PRIMARY_KEY_INDEX; + ::rtl::OUString IS_CLUSTERED; + ::rtl::OUString IS_UNIQUE; + ::rtl::OUString PRIVATE_COLUMN_INDEXES; + ::rtl::OUString HELP_TEXT; + + ::rtl::OUString CATALOG; + ::rtl::OUString IS_ASCENDING; + ReflectionImplementations refl; + + com::sun::star::uno::Sequence< ::rtl::OUString > tablesRowNames; + com::sun::star::uno::Sequence< ::rtl::OUString > columnRowNames; + com::sun::star::uno::Sequence< ::rtl::OUString > primaryKeyNames; + com::sun::star::uno::Sequence< ::rtl::OUString > tablePrivilegesNames; + com::sun::star::uno::Sequence< ::rtl::OUString > schemaNames; + com::sun::star::uno::Sequence< ::rtl::OUString > tableTypeNames; + com::sun::star::uno::Sequence< ::rtl::OUString > typeinfoColumnNames; + com::sun::star::uno::Sequence< ::rtl::OUString > indexinfoColumnNames; + com::sun::star::uno::Sequence< ::rtl::OUString > importedKeysColumnNames; + com::sun::star::uno::Sequence< ::rtl::OUString > resultSetArrayColumnNames; + com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< com::sun::star::uno::Any > > tableTypeData; + + ColumnMetaDataVector typeInfoMetaData; + BaseTypeMap baseTypeMap; + Statics(){} +private: + Statics( const Statics & ); + Statics & operator = ( const Statics & ); +}; + +Statics & getStatics(); + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_tools.cxx connectivity/source/drivers/postgresql/pq_tools.cxx new file mode 100644 index 0000000..c6b16e0 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_tools.cxx @@ -0,0 +1,1232 @@ +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pq_xcontainer.hxx" +#include "pq_tools.hxx" +#include "pq_statics.hxx" + +#include + +using rtl::OUString; +using rtl::OUStringBuffer; + +using com::sun::star::beans::XPropertySet; + +using com::sun::star::lang::XComponent; + +using com::sun::star::sdbc::SQLException; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XConnection; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XRow; + +using com::sun::star::sdbcx::XColumnsSupplier; + +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; + +using com::sun::star::container::XEnumeration; +using com::sun::star::container::XEnumerationAccess; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +rtl::OUString date2String( const com::sun::star::util::Date & x ) +{ + char buffer[64]; + sprintf( buffer, "%d-%02d-%02d", x.Year, x.Month, x.Day ); + return OUString::createFromAscii( buffer ); +} + +com::sun::star::util::Date string2Date( const rtl::OUString &date ) +{ + // Format: Year-Month-Day + com::sun::star::util::Date ret; + + ret.Year = (sal_Int32) rtl_ustr_toInt32( date.pData->buffer, 10 ); + + int index = date.indexOf( '-' ); + if( index >= 0 ) + { + ret.Month = (sal_Int32)rtl_ustr_toInt32( &(date.pData->buffer[ index+1]), 10 ); + int start = index; + index = date.indexOf( '-', start+1 ); + if( index >= 0 ) + { + ret.Day = (sal_Int32)rtl_ustr_toInt32( &date.pData->buffer[index+1], 10 ); + } + } + return ret; +} + +rtl::OUString time2String( const com::sun::star::util::Time & x ) +{ + char buffer[64]; + sprintf( buffer, "%02d:%02d:%02d.%02d", x.Hours, x.Minutes, x.Seconds, x.HundredthSeconds ); + return OUString::createFromAscii( buffer ); + +} + + +com::sun::star::util::Time string2Time( const rtl::OUString & time ) +{ + com::sun::star::util::Time ret; + + sal_Unicode temp[4]; + + temp[0] = time[0]; + temp[1] = time[1]; + temp[2] = 0; + ret.Hours = (sal_Int32)rtl_ustr_toInt32( temp , 10 ); + + temp[0] = time[3]; + temp[1] = time[4]; + ret.Minutes = (sal_Int32)rtl_ustr_toInt32( temp , 10 ); + + temp[0] = time[6]; + temp[1] = time[7]; + ret.Seconds = (sal_Int32)rtl_ustr_toInt32( temp , 10 ); + + if( time.getLength() >9 ) + { + ret.HundredthSeconds = (sal_Int32)rtl_ustr_toInt32( &time[9] , 10 ); + } + return ret; + +} + + + +rtl::OUString dateTime2String( const com::sun::star::util::DateTime & x ) +{ + char buffer[128]; + sprintf( buffer, "%d-%02d-%02d %02d:%02d:%02d.%02d", + x.Year, x.Month, x.Day, + x.Hours, x.Minutes, x.Seconds, x.HundredthSeconds ); + return OUString::createFromAscii( buffer ); + +} + +com::sun::star::util::DateTime string2DateTime( const rtl::OUString & dateTime ) +{ + int space = dateTime.indexOf( ' ' ); + com::sun::star::util::DateTime ret; + + if( space >= 0 ) + { + com::sun::star::util::Date date ( string2Date( OUString( dateTime.getStr(), space ) ) ); + com::sun::star::util::Time time( string2Time( OUString( dateTime.getStr() + space +1 ) ) ); + ret.Day = date.Day; + ret.Month = date.Month; + ret.Year = date.Year; + + ret.Hours = time.Hours; + ret.Minutes = time.Minutes; + ret.Seconds = time.Seconds; + ret.HundredthSeconds = time.HundredthSeconds; + } + return ret; +} + +rtl::OUString concatQualified( const rtl::OUString & a, const rtl::OUString &b) +{ + rtl::OUStringBuffer buf( a.getLength() + 2 + b.getLength() ); + buf.append( a ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "." ) ); + buf.append( b ); + return buf.makeStringAndClear(); +} + +void bufferEscapeConstant( rtl::OUStringBuffer & buf, const rtl::OUString & value, sal_Int32 encoding ) +{ + rtl::OString y = rtl::OUStringToOString( value, encoding ); + rtl::OStringBuffer strbuf( y.getLength() * 2 + 2 ); + int len = PQescapeString( ((char*)strbuf.getStr()), y.getStr() , y.getLength() ); + strbuf.setLength( len ); + buf.append( rtl::OStringToOUString( strbuf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); +} + +void bufferQuoteConstant( rtl::OUStringBuffer & buf, const rtl::OUString & value, sal_Int32 encoding ) +{ + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " '" ) ); + bufferEscapeConstant( buf, value, encoding ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "' " ) ); +} + +void bufferQuoteQualifiedIdentifier( + rtl::OUStringBuffer & buf, const rtl::OUString &schema, const rtl::OUString &name) +{ + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" \"" ) ); + buf.append(schema); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\".\"" ) ); + buf.append( name ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\" " ) ); +} + +void bufferQuoteQualifiedIdentifier( + rtl::OUStringBuffer & buf, + const rtl::OUString &schema, + const rtl::OUString &name, + const rtl::OUString &col) +{ + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" \"" ) ); + buf.append(schema); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\".\"" ) ); + buf.append( name ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\".\"" ) ); + buf.append( col ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\" " ) ); +} + + +void bufferQuoteIdentifier( rtl::OUStringBuffer & buf, const rtl::OUString &toQuote ) +{ + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " \"") ); + buf.append( toQuote ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\" " ) ); +} + + + +rtl::OUString extractStringProperty( + const Reference< XPropertySet > & descriptor, const rtl::OUString &name ) +{ + rtl::OUString value; + descriptor->getPropertyValue( name ) >>= value; + return value; +} + +sal_Bool extractBoolProperty( + const Reference< XPropertySet > & descriptor, const rtl::OUString &name ) +{ + sal_Bool value = sal_False; + descriptor->getPropertyValue( name ) >>= value; + return value; +} + +sal_Int32 extractIntProperty( + const Reference< XPropertySet > & descriptor, const rtl::OUString &name ) +{ + sal_Int32 ret = 0; + descriptor->getPropertyValue( name ) >>= ret; + return ret; +} + +void disposeObject( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > & r ) +{ + Reference< XComponent > comp( r, UNO_QUERY ); + if( comp.is() ) + comp->dispose(); +} + +void disposeNoThrow( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > & r ) +{ + try + { + disposeObject( r ); + } + catch( SQLException & e ) + { + // ignore this + } + +} + +void rollbackNoThrow( const com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & r ) +{ + try + { + Reference< XStatement > stmt = r->createStatement(); + stmt->executeUpdate( getStatics().ROLLBACK ); + + } + catch( SQLException & ) + { + // ignore this + } +} + +Reference< XConnection > extractConnectionFromStatement( const Reference< XInterface > & stmt ) +{ + Reference< XConnection > ret; + + Reference< com::sun::star::sdbc::XStatement > owner( stmt, UNO_QUERY ); + if( owner.is() ) + ret = owner->getConnection(); + else + { + Reference< com::sun::star::sdbc::XPreparedStatement > myowner( stmt, UNO_QUERY ); + if( myowner.is() ) + ret = myowner->getConnection(); + if( ! ret.is() ) + throw SQLException( + ASCII_STR( "PQSDBC: Couldn't retrieve connection from statement" ), + Reference< XInterface > () , rtl::OUString(), 0 , com::sun::star::uno::Any() ); + } + + return ret; + +} + +DisposeGuard::DisposeGuard( const Reference< XInterface > & r ) + : d( r ) +{} + +DisposeGuard::~DisposeGuard() +{ + disposeNoThrow( d ); +} + +TransactionGuard::TransactionGuard( const Reference< XStatement > &stmt ) + : m_stmt( stmt ), + m_commited( sal_False ) +{ + m_stmt->executeUpdate( getStatics().BEGIN ); +} + +void TransactionGuard::commit() +{ + m_stmt->executeUpdate( getStatics().COMMIT ); + m_commited = sal_True; +} + +void TransactionGuard::executeUpdate( const rtl::OUString & sql ) +{ + m_stmt->executeUpdate( sql ); +} + +TransactionGuard::~TransactionGuard() +{ + try + { + if( ! m_commited ) + m_stmt->executeUpdate( getStatics().ROLLBACK ); + } + catch( com::sun::star::uno::Exception & e ) + { + // ignore, we are within a dtor + } + + disposeNoThrow( m_stmt ); +} + + +bool isWhitespace( sal_Unicode c ) +{ + return ' ' == c || 9 == c || 10 == c || 13 == c; +} + +::rtl::OUString extractTableFromInsert( const rtl::OUString & sql ) +{ + rtl::OUString ret; + int i = 0; + for( ; i < sql.getLength() && isWhitespace(sql[i]) ; i++ ); + + if( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( + &sql[i], sql.getLength() - i, "insert" , 6 ) ) + { + i += 6; + for( ; i < sql.getLength() && isWhitespace(sql[i]) ; i++ ); + if( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( + &sql[i], sql.getLength() - i, "into" , 4 ) ) + { + i +=4; + for( ; i < sql.getLength() && isWhitespace(sql[i]) ; i++ ); + int start = i; + bool quote = (sql[i] == '"'); + for( i++ ; i < sql.getLength() ; i ++ ) + { + if( quote && sql[i] == '"' ) + { + for( i++ ; i < sql.getLength() && isWhitespace(sql[i]) ; i++ ); + if( '.' == sql[i] ) + { + for( i++ ; i < sql.getLength() && isWhitespace(sql[i]) ; i++ ); + if( '"' == sql[i] ) + { + // the second part of the table name does not use quotes + // parse on + quote = 0; + } + } + else + { + // end quoted name, ok + break; + } + } + else + { + if( isWhitespace( sql[i] ) ) + { + // found the end of an unquoted name + break; + } + } + } + ret = rtl::OUString( &sql[start], i - start ).trim(); +// printf( "pq_statement: parsed table name %s from insert\n" , +// OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US).getStr() ); + } + } + return ret; +} + + +static bool isOperator( char c ) +{ + bool ret; + switch(c) + { + case '+': + case '-': + case '*': + case '/': + case '<': + case '>': + case '=': + case '~': + case '!': + case '@': + case '#': + case '%': + case '^': + case '&': + case '|': + case '`': + case '?': + case '$': + ret = true; + default: + ret = false; + } + return ret; +} + +void splitSQL( const rtl::OString & sql, OStringVector &vec ) +{ + int length = sql.getLength(); + + int i = 0; + bool singleQuote = false; + bool doubleQuote = false; + int start = 0; + for( ; i < length ; i ++ ) + { + char c = sql[i]; + if( doubleQuote ) + { + if( '"' == c ) + { + vec.push_back( rtl::OString( &sql[start], i-start+1 ) ); + start = i + 1; + doubleQuote = false; + } + } + else if( singleQuote ) + { + if( '\'' == c && '\'' == sql[i+1] ) + { + // two subsequent single quotes within a quoted string + // mean a single quote within the string + i ++; + } + else if( '\'' == c ) + { + vec.push_back( rtl::OString( &sql[start], i - start +1 ) ); + start = i + 1; // leave single quotes ! + singleQuote = false; + } + } + else + { + if( '"' == c ) + { + vec.push_back( rtl::OString( &sql[start], i - start ) ); + doubleQuote = true; + start = i; + } + else if( '\'' == c ) + { + vec.push_back( rtl::OString( &sql[start], i - start ) ); + singleQuote = true; + start = i; + } + } + } + if( start < i ) + vec.push_back( rtl::OString( &sql[start] , i - start ) ); + +// for( i = 0 ; i < vec.size() ; i ++ ) +// printf( "%s!" , vec[i].getStr() ); +// printf( "\n" ); + +} + +void tokenizeSQL( const rtl::OString & sql, OStringVector &vec ) +{ + int length = sql.getLength(); + + int i = 0; + bool singleQuote = false; + bool doubleQuote = false; + int start = 0; + for( ; i < length ; i ++ ) + { + char c = sql[i]; + if( doubleQuote ) + { + if( '"' == c ) + { + vec.push_back( rtl::OString( &sql[start], i-start ) ); + start = i + 1; + doubleQuote = false; + } + } + else if( singleQuote ) + { + if( '\'' == c ) + { + vec.push_back( rtl::OString( &sql[start], i - start +1 ) ); + start = i + 1; // leave single quotes ! + singleQuote = false; + } + } + else + { + if( '"' == c ) + { + doubleQuote = true; + start = i +1; // skip double quotes ! + } + else if( '\'' == c ) + { + singleQuote = true; + start = i; // leave single quotes + } + else if( isWhitespace( c ) ) + { + if( i == start ) + start ++; // skip additional whitespace + else + { + vec.push_back( rtl::OString( &sql[start], i - start ) ); + start = i +1; + } + } + else if( ',' == c || isOperator( c ) || '(' == c || ')' == c ) + { + if( i - start ) + vec.push_back( rtl::OString( &sql[start], i - start ) ); + vec.push_back( rtl::OString( &sql[i], 1 ) ); + start = i + 1; + } + else if( '.' == c ) + { + if( ( i > start && sql[start] >= '0' && sql[start] <= '9' ) || + ( i == start && i > 1 && isWhitespace( sql[i-1] ) ) ) + { + // ignore, is a literal + } + else + { + if( i - start ) + vec.push_back( rtl::OString( &sql[start], i - start ) ); + vec.push_back( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "." ) ) ); + start = i + 1; + } + } + } + } + if( start < i ) + vec.push_back( rtl::OString( &sql[start] , i - start ) ); + +// for( i = 0 ; i < vec.size() ; i ++ ) +// printf( "%s!" , vec[i].getStr() ); +// printf( "\n" ); +} + + +void splitConcatenatedIdentifier( const rtl::OUString & source, rtl::OUString *first, rtl::OUString *second) +{ + OStringVector vec; + tokenizeSQL( rtl::OUStringToOString( source, RTL_TEXTENCODING_UTF8 ), vec ); + if( vec.size() == 3 ) + { + *first = rtl::OStringToOUString( vec[0] , RTL_TEXTENCODING_UTF8 ); + *second = rtl::OStringToOUString( vec[2], RTL_TEXTENCODING_UTF8 ); + } +} + +typedef std::vector< sal_Int32 , Allocator< sal_Int32 > > IntVector; + + +rtl::OUString array2String( const com::sun::star::uno::Sequence< Any > &seq ) +{ + OUStringBuffer buf(128); + int len = seq.getLength(); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "{" ) ); + for( int i = 0 ; i < len ; i ++ ) + { + OUString element; + seq[i] >>= element; + + if( i > 0 ) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(",") ); + int strLength = element.getLength(); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\"") ); + for( int j = 0 ; j < strLength ; j ++ ) + { + sal_Unicode c = element[j]; + if( c == '\\' || c == '"' || c == '{' || c == '}' ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\\" ) ); + } + buf.append( c ); + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\"" ) ); + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "}" ) ); + return buf.makeStringAndClear(); +} + +typedef +std::vector +< + com::sun::star::uno::Any, + Allocator< com::sun::star::uno::Any > +> AnyVector; + +com::sun::star::uno::Sequence< Any > parseArray( const rtl::OUString & str ) throw( SQLException ) +{ + com::sun::star::uno::Sequence< Any > ret; + + int len = str.getLength(); + bool doubleQuote = false; + int brackets = 0; + int i = 0; + + OUStringBuffer current; + AnyVector elements; + bool doubleQuotedValue = false; + while( i < len ) + { + sal_Unicode c = str[i]; + sal_Unicode cnext = str[i+1]; + if( doubleQuote ) + { + if( '\\' == c ) + { + i ++; + current.append( cnext ); + } + else if( '"' == c ) + { + doubleQuote = false; + doubleQuotedValue = true; // signal, that there was an empty element + } + else + { + current.append( c ); + } + } + else if ( '{' == c ) + { + brackets ++; + } + else if( '}' == c ) + { + brackets --; + if( brackets < 0 ) + { + + OUStringBuffer buf; + buf.appendAscii( "error during array parsing, didn't expect a } at position " ); + buf.append( (sal_Int32) i ); + buf.appendAscii( " ('" ); + buf.append( str ); + buf.appendAscii( "')" ); + throw SQLException( + buf.makeStringAndClear(), + Reference< XInterface > (), rtl::OUString(), 1, Any() ); + } + if( brackets == 0 ) + { + if( current.getLength() > 0 || doubleQuotedValue ) + elements.push_back( makeAny( current.makeStringAndClear() ) ); + } + else + { + current.append( c ); + } + } + else if( '"' == c ) + { +// if( current.getLength() != 0 ) +// { +// OUStringBuffer buf; +// buf.appendAscii( "error during array parsing, didn't expect a \" at position " ); +// buf.append( i ); +// buf.append( " ('" ); +// buf.append( str ); +// buf.append( "')" ); +// throw SDBCException( +// buf.makeStringAndClear(), +// Reference< XInterface > (), 1, Any() ); +// } +// else +// { + doubleQuote = true; +// } + } + else if( ',' == c && brackets == 1) + { + doubleQuotedValue = false; + elements.push_back( makeAny( current.makeStringAndClear() ) ); + } + else if( isWhitespace( c ) ) + { + // ignore whitespace without quotes + } + else + { + current.append( c ); + } + i++; + } + ret = Sequence< Any > ( &elements[0] , elements.size() ); + return ret; +} + +com::sun::star::uno::Sequence< sal_Int32 > parseIntArray( const ::rtl::OUString & str ) +{ + sal_Int32 start = 0; + IntVector vec; +// printf( ">%s<\n" , OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() ); + for( sal_Int32 i = str.indexOf( ' ' ) ; i != -1 ; i = str.indexOf( ' ', start) ) + { + vec.push_back( (sal_Int32)rtl_ustr_toInt32( &str.pData->buffer[start], 10 ) ); +// printf( "found %d\n" , rtl_ustr_toInt32( &str.pData->buffer[start], 10 )); + start = i + 1; + } + vec.push_back( (sal_Int32)rtl_ustr_toInt32( &str.pData->buffer[start], 10 ) ); +// printf( "found %d\n" , rtl_ustr_toInt32( &str.pData->buffer[start], 10 )); + return Sequence< sal_Int32 > ( &vec[0], vec.size() ); +} + +void fillAttnum2attnameMap( + Int2StringMap &map, + const Reference< com::sun::star::sdbc::XConnection > &conn, + const rtl::OUString &schema, + const rtl::OUString &table ) +{ + Reference< XPreparedStatement > prep = conn->prepareStatement( + ASCII_STR( "SELECT attname,attnum " + "FROM pg_attribute " + "INNER JOIN pg_class ON attrelid = pg_class.oid " + "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid " + "WHERE relname=? AND nspname=?" ) ); + + Reference< XParameters > paras( prep, UNO_QUERY ); + paras->setString( 1 , table ); + paras->setString( 2 , schema ); + Reference< XResultSet > rs = prep->executeQuery(); + + Reference< XRow > xRow( rs , UNO_QUERY ); + while( rs->next() ) + { + map[ xRow->getInt(2) ] = xRow->getString(1); + } +} + +::rtl::OString extractSingleTableFromSelect( const OStringVector &vec ) +{ + rtl::OString ret; + int token = 0; + + if( 0 == rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( + vec[0].pData->buffer, vec[0].pData->length, "select" , 6 , 6 ) ) + { + for( token = 1; token < vec.size() ; token ++ ) + { + if( 0 == rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( + vec[token].getStr(), vec[token].getLength(), "from" , 4 , 4 ) ) + { + // found from + break; + } + } + token ++; + + if( token < vec.size() && 0 == rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( + vec[token].pData->buffer, vec[token].pData->length, "only " , 4 , 4 ) ) + { + token ++; + } + + if( token < vec.size() && rtl_str_compare_WithLength( + vec[token].getStr(), vec[token].getLength(), + RTL_CONSTASCII_STRINGPARAM("(") ) ) + { + // it is a table or a function name + rtl::OStringBuffer buf(128); + if( '"' == vec[token][0] ) + buf.append( &(vec[token][1]) , vec[token].getLength() -2 ); + else + buf.append( vec[token] ); + token ++; + + if( token < vec.size() ) + { + if( rtl_str_compare_WithLength( + vec[token].getStr(), vec[token].getLength(), + RTL_CONSTASCII_STRINGPARAM( "." ) ) == 0 ) + { + buf.append( vec[token] ); + token ++; + if( token < vec.size() ) + { + if( '"' == vec[token][0] ) + buf.append( &(vec[token][1]) , vec[token].getLength() -2 ); + else + buf.append( vec[token] ); + token ++; + } + } + } + + ret = buf.makeStringAndClear(); + // now got my table candidate + + if( token < vec.size() && rtl_str_compare_WithLength( + vec[token].getStr(), vec[token].getLength(), + RTL_CONSTASCII_STRINGPARAM( "(" ) ) == 0 ) + { + // whoops, it is a function + ret = rtl::OString(); + } + else + { + if( token < vec.size() ) + { + if( 0 == rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( + vec[token].pData->buffer, vec[token].pData->length, "as" , 2, 2 ) ) + { + token += 2; // skip alias + } + } + + if( token < vec.size() ) + { + if( rtl_str_compare_WithLength( + vec[token].getStr(), vec[token].getLength(), + RTL_CONSTASCII_STRINGPARAM( "," ) ) == 0 ) + { + // whoops, multiple tables are used + ret = rtl::OString(); + } + else + { + static const char * forbiddenKeywords[] = + { "join", "natural", "outer", "inner", "left", "right", "full" , 0 }; + for( int i = 0 ; forbiddenKeywords[i] ; i ++ ) + { + if( 0 == rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( + vec[token].pData->buffer, vec[token].pData->length, + forbiddenKeywords[i], strlen(forbiddenKeywords[i]), + strlen(forbiddenKeywords[i]) ) ) + { + // whoops, it is a join + ret = rtl::OString(); + } + } + } + } + } + } + } + return ret; + +} + +com::sun::star::uno::Sequence< sal_Int32 > string2intarray( const ::rtl::OUString & str ) +{ + com::sun::star::uno::Sequence< sal_Int32 > ret; + if( str.getLength() > 1 && '{' == str[0] ) + { + std::vector< sal_Int32, Allocator< sal_Int32 > > vec; + sal_Int32 start = 0; + do + { + start ++; + vec.push_back( (sal_Int32)rtl_ustr_toInt32( &str[start], 10 ) ); + start = str.indexOf( ',' , start ); + } while( start != -1 ); + ret = com::sun::star::uno::Sequence< sal_Int32 > ( &vec[0] , vec.size() ); + } + return ret; +} + + +Sequence< rtl::OUString > convertMappedIntArray2StringArray( + const Int2StringMap &map, const Sequence< sal_Int32 > &intArray ) +{ + Sequence< ::rtl::OUString > ret( intArray.getLength() ); + for( int i = 0; i < intArray.getLength() ; i ++ ) + { + Int2StringMap::const_iterator ii = map.find( intArray[i] ); + if( ii != map.end() ) + ret[i] = ii->second; + } + return ret; +} + + +::rtl::OUString sqltype2string( const Reference< XPropertySet > & desc ) +{ + OUStringBuffer typeName; + typeName.append( extractStringProperty( desc, getStatics().TYPE_NAME ) ); + sal_Int32 precision = extractIntProperty( desc, getStatics().PRECISION ); + + if( precision ) + { + switch( extractIntProperty( desc, getStatics().TYPE ) ) + { + case com::sun::star::sdbc::DataType::VARBINARY: + case com::sun::star::sdbc::DataType::VARCHAR: + case com::sun::star::sdbc::DataType::CHAR: + { + typeName.appendAscii( RTL_CONSTASCII_STRINGPARAM( "(" ) ); + typeName.append( precision ); + typeName.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) ); + break; + } + case com::sun::star::sdbc::DataType::DECIMAL: + case com::sun::star::sdbc::DataType::NUMERIC: + { + typeName.appendAscii( RTL_CONSTASCII_STRINGPARAM( "(" ) ); + typeName.append( precision ); + typeName.appendAscii( RTL_CONSTASCII_STRINGPARAM( "," ) ); + typeName.append( extractIntProperty( desc, getStatics().SCALE ) ); + typeName.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) ); + break; + } + default: + ((void)0); + } + } + return typeName.makeStringAndClear(); +} + + + + +static void keyType2String( OUStringBuffer & buf, sal_Int32 keyType ) +{ + if( com::sun::star::sdbc::KeyRule::CASCADE == keyType ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "CASCADE " ) ); + } + else if( com::sun::star::sdbc::KeyRule::RESTRICT == keyType ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "RESTRICT " ) ); + } + else if( com::sun::star::sdbc::KeyRule::SET_DEFAULT == keyType ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SET DEFAULT " ) ); + } + else if( com::sun::star::sdbc::KeyRule::SET_NULL == keyType ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SET NULL " ) ); + } + else //if( com::sun::star::sdbc::KeyRule::NO_ACTION == keyType ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "NO ACTION " ) ); + } +} + +void bufferKey2TableConstraint( + OUStringBuffer &buf, const Reference< XPropertySet > &key ) +{ + Statics &st = getStatics(); + sal_Int32 type = extractIntProperty( key, st.TYPE ); + OUString referencedTable = extractStringProperty( key, st.REFERENCED_TABLE ); + sal_Int32 updateRule = extractIntProperty( key, st.UPDATE_RULE ); + sal_Int32 deleteRule = extractIntProperty( key, st.DELETE_RULE ); + bool foreign = false; + if( type == com::sun::star::sdbcx::KeyType::UNIQUE ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "UNIQUE( " ) ); + } + else if( type == com::sun::star::sdbcx::KeyType::PRIMARY ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "PRIMARY KEY( " ) ); + } + else if( type == com::sun::star::sdbcx::KeyType::FOREIGN ) + { + foreign = true; + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "FOREIGN KEY( " ) ); + } + + Reference< XColumnsSupplier > columns( key, UNO_QUERY ); + if( columns.is() ) + { + Reference< XEnumerationAccess > colEnumAccess( columns->getColumns(), UNO_QUERY ); + if( colEnumAccess.is() ) + { + Reference< XEnumeration > colEnum = colEnumAccess->createEnumeration(); + bool first = true; + while(colEnum.is() && colEnum->hasMoreElements() ) + { + if( first ) + { + first = false; + } + else + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) ); + } + Reference< XPropertySet > keyColumn( colEnum->nextElement(), UNO_QUERY ); + bufferQuoteIdentifier(buf, extractStringProperty( keyColumn, st.NAME ) ); + } + } + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ") " )); + + if( foreign ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "REFERENCES " ) ); + OUString schema; + OUString tableName; + splitConcatenatedIdentifier( referencedTable, &schema, &tableName ); + bufferQuoteQualifiedIdentifier(buf , schema, tableName); + if(columns.is() ) + { + Reference< XEnumerationAccess > colEnumAccess( columns->getColumns(), UNO_QUERY); + if( colEnumAccess.is() ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " (" ) ); + Reference< XEnumeration > colEnum(colEnumAccess->createEnumeration()); + bool first = true; + while(colEnum.is() && colEnum->hasMoreElements() ) + { + if( first ) + { + first = false; + } + else + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) ); + } + Reference< XPropertySet > keyColumn( colEnum->nextElement(), UNO_QUERY ); + bufferQuoteIdentifier( + buf, extractStringProperty( keyColumn, st.RELATED_COLUMN ) ); + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ") " ) ); + } + } + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ON DELETE " ) ); + keyType2String( buf, deleteRule ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ON UPDATE " ) ); + keyType2String( buf, updateRule ); + } + +} + +static bool equalsIgnoreCase( const rtl::OString & str, const char *str2, int length2 ) +{ + return 0 == rtl_str_compareIgnoreAsciiCase_WithLength( + str.pData->buffer, str.pData->length, str2, length2 ); +} + +void extractNameValuePairsFromInsert( String2StringMap & map, const rtl::OString & lastQuery ) +{ + OStringVector vec; + tokenizeSQL( lastQuery, vec ); + + int nSize = vec.size(); +// printf( "1 %d\n", nSize ); + if( nSize > 6 && + equalsIgnoreCase( vec[0] , RTL_CONSTASCII_STRINGPARAM( "insert" ) ) && + equalsIgnoreCase( vec[1] , RTL_CONSTASCII_STRINGPARAM( "into" ) ) ) + { + int n = 2; + +// printf( "1a\n" ); + // extract table name + rtl::OString tableName; + if( equalsIgnoreCase( vec[n+1], RTL_CONSTASCII_STRINGPARAM( "." ) ) ) + { + tableName = vec[n]; + tableName += vec[n+1]; + tableName += vec[n+2]; + n +=2; + } + else + { + tableName = vec[n]; + } + + OStringVector names; + n ++; + if( equalsIgnoreCase( vec[n], RTL_CONSTASCII_STRINGPARAM( "(" ) ) ) + { +// printf( "2\n" ); + // extract names + n++; + while( nSize > n && ! equalsIgnoreCase(vec[n] , RTL_CONSTASCII_STRINGPARAM( ")" ) ) ) + { + names.push_back( vec[n] ); + if( nSize > n+1 && equalsIgnoreCase( vec[n+1] , RTL_CONSTASCII_STRINGPARAM( "," ) ) ) + { + n ++; + } + n++; + } + n++; + + // now read the values + if( nSize > n +1 && equalsIgnoreCase( vec[n], RTL_CONSTASCII_STRINGPARAM("VALUES") ) && + equalsIgnoreCase(vec[n+1], RTL_CONSTASCII_STRINGPARAM( "(" ) ) ) + { + n +=2; +// printf( "3\n" ); + for ( int i = 0 ; i < names.size() && nSize > n ; i ++ ) + { + map[names[i]] = vec[n]; + if( nSize > n+1 && equalsIgnoreCase( vec[n+1] , RTL_CONSTASCII_STRINGPARAM(",") ) ) + { + n ++; + } + n++; + } + } + } + } +} + +rtl::OUString querySingleValue( + const com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > &connection, + const rtl::OUString &query ) +{ + OUString ret; + Reference< XStatement > stmt = connection->createStatement(); + DisposeGuard guard( stmt ); + Reference< XResultSet > rs = stmt->executeQuery( query ); + Reference< XRow > xRow( rs, UNO_QUERY ); + if( rs->next() ) + ret = xRow->getString( 1 ); + return ret; +} + + +// copied from connectivity/source/dbtools, can't use the function directly +bool implSetObject( const Reference< XParameters >& _rxParameters, + const sal_Int32 _nColumnIndex, const Any& _rValue) +{ + sal_Bool bSuccessfullyReRouted = sal_True; + switch (_rValue.getValueTypeClass()) + { + case typelib_TypeClass_HYPER: + { + sal_Int64 nValue = 0; + _rxParameters->setLong( _nColumnIndex, nValue ); + } + break; + + case typelib_TypeClass_VOID: + _rxParameters->setNull(_nColumnIndex,com::sun::star::sdbc::DataType::VARCHAR); + break; + + case typelib_TypeClass_STRING: + _rxParameters->setString(_nColumnIndex, *(rtl::OUString*)_rValue.getValue()); + break; + + case typelib_TypeClass_BOOLEAN: + _rxParameters->setBoolean(_nColumnIndex, *(sal_Bool *)_rValue.getValue()); + break; + + case typelib_TypeClass_BYTE: + _rxParameters->setByte(_nColumnIndex, *(sal_Int8 *)_rValue.getValue()); + break; + + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_SHORT: + _rxParameters->setShort(_nColumnIndex, *(sal_Int16*)_rValue.getValue()); + break; + + case typelib_TypeClass_CHAR: + _rxParameters->setString(_nColumnIndex, ::rtl::OUString((sal_Unicode *)_rValue.getValue(),1)); + break; + + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_LONG: + _rxParameters->setInt(_nColumnIndex, *(sal_Int32*)_rValue.getValue()); + break; + + case typelib_TypeClass_FLOAT: + _rxParameters->setFloat(_nColumnIndex, *(float*)_rValue.getValue()); + break; + + case typelib_TypeClass_DOUBLE: + _rxParameters->setDouble(_nColumnIndex, *(double*)_rValue.getValue()); + break; + + case typelib_TypeClass_SEQUENCE: + if (_rValue.getValueType() == ::getCppuType((const Sequence< sal_Int8 > *)0)) + { + _rxParameters->setBytes(_nColumnIndex, *(Sequence*)_rValue.getValue()); + } + else + bSuccessfullyReRouted = sal_False; + break; + case typelib_TypeClass_STRUCT: + if (_rValue.getValueType() == ::getCppuType((const com::sun::star::util::DateTime*)0)) + _rxParameters->setTimestamp(_nColumnIndex, *(com::sun::star::util::DateTime*)_rValue.getValue()); + else if (_rValue.getValueType() == ::getCppuType((const com::sun::star::util::Date*)0)) + _rxParameters->setDate(_nColumnIndex, *(com::sun::star::util::Date*)_rValue.getValue()); + else if (_rValue.getValueType() == ::getCppuType((const com::sun::star::util::Time*)0)) + _rxParameters->setTime(_nColumnIndex, *(com::sun::star::util::Time*)_rValue.getValue()); + else + bSuccessfullyReRouted = sal_False; + break; + + case typelib_TypeClass_INTERFACE: + { + Reference< com::sun::star::io::XInputStream > xStream; + if (_rValue >>= xStream) + { + _rValue >>= xStream; + _rxParameters->setBinaryStream(_nColumnIndex, xStream, xStream->available()); + break; + } + } + // run through + default: + bSuccessfullyReRouted = sal_False; + + } + + return bSuccessfullyReRouted; +} + + +} diff --git connectivity/source/drivers/postgresql/pq_tools.hxx connectivity/source/drivers/postgresql/pq_tools.hxx new file mode 100644 index 0000000..4ea1002 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_tools.hxx @@ -0,0 +1,201 @@ +/************************************************************************* + * + * $RCSfile: pq_tools.hxx,v $ + * + * $Revision: 1.1.2.7 $ + * + * last change: $Author: jbu $ $Date: 2008/07/07 21:37:11 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_TOOLS_ +#define _PQ_TOOLS_ + +#include +#include +#include +#include +#include + +#include +#include + +#include +namespace pq_sdbc_driver +{ +bool isWhitespace( sal_Unicode c ); + +rtl::OUString date2String( const com::sun::star::util::Date & date ); +com::sun::star::util::Date string2Date( const rtl::OUString & str ); + +rtl::OUString time2String( const com::sun::star::util::Time & time ); +com::sun::star::util::Time string2Time( const rtl::OUString & str ); + +rtl::OUString dateTime2String( const com::sun::star::util::DateTime & dateTime ); +com::sun::star::util::DateTime string2DateTime( const rtl::OUString & dateTime ); + +rtl::OUString concatQualified( const rtl::OUString & a, const rtl::OUString &b); + +void bufferQuoteConstant( rtl::OUStringBuffer & buf, const rtl::OUString & str, sal_Int32 encoding ); + +void bufferEscapeConstant( rtl::OUStringBuffer & buf, const rtl::OUString & str, sal_Int32 encoding ); + +::rtl::OUString sqltype2string( + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > & column ); + + +void bufferQuoteQualifiedIdentifier( + rtl::OUStringBuffer & buf, const rtl::OUString &schema, const rtl::OUString &name); + +void bufferQuoteQualifiedIdentifier( + rtl::OUStringBuffer & buf, + const rtl::OUString &schema, + const rtl::OUString &name, + const rtl::OUString &col); + +void bufferQuoteIdentifier( rtl::OUStringBuffer & buf, const rtl::OUString &toQuote ); +void bufferKey2TableConstraint( + rtl::OUStringBuffer &buf, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > &key ); + +rtl::OUString extractStringProperty( + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > & descriptor, + const rtl::OUString &name ); + +sal_Int32 extractIntProperty( + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > & descriptor, + const rtl::OUString &name ); + +sal_Bool extractBoolProperty( + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > & descriptor, + const rtl::OUString &name ); + +void disposeNoThrow( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > & r ); +void disposeObject( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > & r ); + +void rollbackNoThrow( const com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & r ); + +::rtl::OUString extractTableFromInsert( const rtl::OUString & sql ); +::rtl::OString extractSingleTableFromSelect( const OStringVector &vec ); + +void tokenizeSQL( const rtl::OString & sql, OStringVector &vec ); +void splitSQL( const rtl::OString & sql, OStringVector &vec ); +com::sun::star::uno::Sequence< sal_Int32 > parseIntArray( const ::rtl::OUString & str ); +com::sun::star::uno::Sequence< com::sun::star::uno::Any > parseArray( const ::rtl::OUString & str ) + throw( com::sun::star::sdbc::SQLException ); + +rtl::OUString array2String( const com::sun::star::uno::Sequence< com::sun::star::uno::Any > &seq ); + +com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > extractConnectionFromStatement( + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > & stmt ); + +void splitConcatenatedIdentifier( const rtl::OUString & source, rtl::OUString *first, rtl::OUString *second); + + +void fillAttnum2attnameMap( + Int2StringMap &map, + const com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > &conn, + const rtl::OUString &schema, + const rtl::OUString &table ); + +com::sun::star::uno::Sequence< sal_Int32 > string2intarray( const ::rtl::OUString & str ); + +com::sun::star::uno::Sequence< rtl::OUString > convertMappedIntArray2StringArray( + const Int2StringMap &map, const com::sun::star::uno::Sequence< sal_Int32> &source ); + +typedef std::hash_map +< + ::rtl::OString, + ::rtl::OString, + ::rtl::OStringHash, + ::std::equal_to< rtl::OString >, + Allocator< ::std::pair< rtl::OString, ::rtl::OString > > +> String2StringMap; + +rtl::OUString querySingleValue( + const com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > &connection, + const rtl::OUString &query ); + +void extractNameValuePairsFromInsert( String2StringMap & map, const rtl::OString & lastQuery ); +sal_Int32 typeNameToDataType( const rtl::OUString &typeName, const rtl::OUString &typtype ); + +// copied from connectivity/source/dbtools, can't use the function directly +bool implSetObject( const com::sun::star::uno::Reference< com::sun::star::sdbc::XParameters >& _rxParameters, + const sal_Int32 _nColumnIndex, const com::sun::star::uno::Any& _rValue); + +class DisposeGuard +{ + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > d; +public: + DisposeGuard(const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > & r ); + ~DisposeGuard(); + +}; + +class TransactionGuard +{ + com::sun::star::uno::Reference< com::sun::star::sdbc::XStatement > m_stmt; + sal_Bool m_commited; +public: + /// takes over ownership of given statemet + TransactionGuard( const com::sun::star::uno::Reference< com::sun::star::sdbc::XStatement > &stmt ); + ~TransactionGuard( ); + + void commit(); + void executeUpdate( const rtl::OUString & sql ); +}; + +} + +#endif diff --git connectivity/source/drivers/postgresql/pq_updateableresultset.cxx connectivity/source/drivers/postgresql/pq_updateableresultset.cxx new file mode 100644 index 0000000..7efa005 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_updateableresultset.cxx @@ -0,0 +1,569 @@ +#include +#include + +#include +#include + +#include +// #include + +#include "pq_updateableresultset.hxx" +#include "pq_resultsetmetadata.hxx" +#include "pq_tools.hxx" +#include "pq_statics.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OStringBuffer; +using rtl::OString; + +using com::sun::star::uno::Reference; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Any; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::sdbc::XGeneratedResultSet; +using com::sun::star::sdbc::XResultSetMetaDataSupplier; +using com::sun::star::sdbc::SQLException; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XColumnLocate; +using com::sun::star::sdbc::XResultSetUpdate; +using com::sun::star::sdbc::XRowUpdate; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XStatement; + +using com::sun::star::beans::XFastPropertySet; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::XMultiPropertySet; + +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +namespace pq_sdbc_driver +{ + + +com::sun::star::uno::Reference< com::sun::star::sdbc::XCloseable > UpdateableResultSet::createFromPGResultSet( + const ::rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner, + ConnectionSettings **ppSettings, + PGresult *result, + const rtl::OUString &schema, + const rtl::OUString &table, + const com::sun::star::uno::Sequence< ::rtl::OUString > &primaryKey ) +{ + ConnectionSettings *pSettings = *ppSettings; + sal_Int32 columnCount = PQnfields( result ); + sal_Int32 rowCount = PQntuples( result ); + Sequence< OUString > columnNames( columnCount ); + for( int i = 0 ; i < columnCount ; i ++ ) + { + char * name = PQfname( result, i ); + columnNames[i] = rtl::OUString( name, strlen(name), pSettings->encoding ); + } + Sequence< Sequence< Any > > data( rowCount ); + + // copy all the data into unicode strings (also binaries, as we yet + // don't know, what a binary is and what not!) + for( int row = 0 ; row < rowCount ; row ++ ) + { + Sequence< Any > aRow( columnCount ); + for( int col = 0 ; col < columnCount ; col ++ ) + { + if( ! PQgetisnull( result, row, col ) ) + { + char * val = PQgetvalue( result, row, col ); + + aRow[col] = makeAny( + rtl::OUString( val, strlen( val ) , (*ppSettings)->encoding ) ); + } + } + data[row] = aRow; + } + + UpdateableResultSet *pRS = new UpdateableResultSet( + mutex, owner, columnNames, data, ppSettings, schema, table , primaryKey ); + + Reference ret = pRS; // give it an refcount + + pRS->m_meta = new ResultSetMetaData( mutex, pRS,0, ppSettings, result, schema, table ); + + PQclear( result ); // we don't need it anymore + + return ret; +} + +static void bufferQuoteAnyConstant( rtl::OUStringBuffer & buf, const Any &val ) +{ + if( val.hasValue() ) + { + OUString str; + val >>= str; + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "'" ) ); + buf.append( str ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "'" ) ); + } + else + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "NULL" ) ); +} + + +com::sun::star::uno::Any UpdateableResultSet::queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException) +{ + Any ret = SequenceResultSet::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< XResultSetUpdate * > ( this ), + static_cast< XRowUpdate * > ( this ) ); + return ret; +} + + +com::sun::star::uno::Sequence< com::sun::star::uno::Type > UpdateableResultSet::getTypes() + throw( com::sun::star::uno::RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< XResultSetUpdate> *) 0 ), + getCppuType( (Reference< XRowUpdate> *) 0 ), + SequenceResultSet::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); + +} + +com::sun::star::uno::Sequence< sal_Int8> UpdateableResultSet::getImplementationId() + throw( com::sun::star::uno::RuntimeException ) +{ + static cppu::OImplementationId *pId; + if( ! pId ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( ! pId ) + { + static cppu::OImplementationId id(sal_False); + pId = &id; + } + } + return pId->getImplementationId(); +} + +OUString UpdateableResultSet::buildWhereClause() +{ + OUString ret; + if( m_primaryKey.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " WHERE " ) ); + for( int i = 0 ; i < m_primaryKey.getLength() ; i ++ ) + { + if( i > 0 ) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " AND " ) ); + sal_Int32 index = findColumn( m_primaryKey[i] ); + bufferQuoteIdentifier( buf, m_primaryKey[i] ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ) ); + bufferQuoteConstant( buf, getString( index ), (*m_ppSettings)->encoding ); + } + ret = buf.makeStringAndClear(); + } + return ret; +} + + +void UpdateableResultSet::insertRow( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + if( isLog( *m_ppSettings, LogLevel::INFO ) ) + { + log( *m_ppSettings, LogLevel::INFO,"UpdateableResultSet::insertRow got called" ); + } + if( ! m_insertRow ) + throw SQLException( + ASCII_STR("pq_resultset.insertRow: moveToInsertRow has not been called !" ), + *this, OUString(), 1, Any() ); + + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "INSERT INTO " ) ); + bufferQuoteQualifiedIdentifier( buf, m_schema, m_table ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ( " ) ); + + int i; + int columns = 0; + for( i = 0 ; i < m_updateableField.size() ; i++ ) + { + if( m_updateableField[i].isTouched ) + { + if( columns > 0 ) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) ); + columns ++; + bufferQuoteIdentifier( buf, m_columnNames[i]); + } + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ) VALUES ( " ) ); + + columns = 0; + for( i = 0 ; i < m_updateableField.size() ; i ++ ) + { + if( m_updateableField[i].isTouched ) + { + if( columns > 0 ) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " , " ) ); + columns ++; + bufferQuoteAnyConstant( buf, m_updateableField[i].value ); + +// OUString val; +// m_updateableField[i].value >>= val; +// buf.append( val ); +// rtl::OStringToOUString(val, (*m_ppSettings)->encoding ) ); + } + } + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " )" ) ); + + Reference< XStatement > stmt = + extractConnectionFromStatement(m_owner)->createStatement(); + DisposeGuard dispGuard( stmt ); + stmt->executeUpdate( buf.makeStringAndClear() ); + + // reflect the changes ! + m_rowCount ++; + m_data.realloc( m_rowCount ); + m_data[m_rowCount-1] = Sequence< Any > ( m_fieldCount ); + Reference< XGeneratedResultSet > result( stmt, UNO_QUERY ); + if( result.is() ) + { + Reference< XResultSet > rs = result->getGeneratedValues(); + if( rs.is() && rs->next() ) + { + Reference< XColumnLocate > columnLocate( rs, UNO_QUERY ); + Reference< XRow> xRow ( rs, UNO_QUERY ); + for( i = 0 ; i < m_fieldCount ; i++ ) + { + int field = columnLocate->findColumn( m_columnNames[i] ); + if( field >= 1 ) + { + m_data[m_rowCount-1][i] <<= xRow->getString( field ); +// printf( "adding %s %s\n" , +// OUStringToOString( m_columnNames[i], RTL_TEXTENCODING_ASCII_US).getStr(), +// OUStringToOString( xRow->getString( field ), RTL_TEXTENCODING_ASCII_US).getStr() ); + + } + } + } + else + { + // do the best we can ( DEFAULT and AUTO increment values fail ! ) + for( int i = 0 ; i < m_fieldCount ; i ++ ) + { + if( m_updateableField[i].isTouched ) + m_data[m_rowCount-1][i] = m_updateableField[i].value; + } + } + } + + // cleanup + m_updateableField = UpdateableFieldVector(); +} + +void UpdateableResultSet::updateRow( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + if( isLog( *m_ppSettings, LogLevel::INFO ) ) + { + log( *m_ppSettings, LogLevel::INFO,"UpdateableResultSet::updateRow got called" ); + } + if( m_insertRow ) + throw SQLException( + ASCII_STR("pq_resultset.updateRow: moveToCurrentRow has not been called !" ), + *this, OUString(), 1, Any() ); + + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "UPDATE " ) ); + bufferQuoteQualifiedIdentifier( buf, m_schema, m_table ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SET " ) ); + + int columns = 0,i; + for( i = 0; i < m_updateableField.size() ; i ++ ) + { + if( m_updateableField[i].isTouched ) + { + if( columns > 0 ) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) ); + columns ++; + + buf.append( m_columnNames[i] ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = " ) ); + bufferQuoteAnyConstant( buf, m_updateableField[i].value ); +// OUString val; +// m_updateableField[i].value >>= val; +// bufferQuoteConstant( buf, val ): +// buf.append( val ); + } + } + buf.append( buildWhereClause() ); + + Reference< XStatement > stmt = extractConnectionFromStatement(m_owner)->createStatement(); + DisposeGuard dispGuard( stmt ); + stmt->executeUpdate( buf.makeStringAndClear() ); + + // reflect the changes ! + for( i = 0 ; i < m_fieldCount ; i ++ ) + { + if( m_updateableField[i].isTouched ) + m_data[m_row][i] = m_updateableField[i].value; + } + m_updateableField = UpdateableFieldVector(); +} + +void UpdateableResultSet::deleteRow( ) throw (SQLException, RuntimeException) +{ + if( isLog( *m_ppSettings, LogLevel::INFO ) ) + { + log( *m_ppSettings, LogLevel::INFO,"UpdateableResultSet::deleteRow got called" ); + } + if( m_insertRow ) + throw SQLException( + ASCII_STR("pq_resultset.deleteRow: deleteRow cannot be called when on insert row !" ), + *this, OUString(), 1, Any() ); + + if( m_row < 0 || m_row >= m_rowCount ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "deleteRow cannot be called on invalid row (" ); + buf.append( m_row ); + buf.appendAscii( ")" ); + throw SQLException( buf.makeStringAndClear() , *this, OUString(), 0, Any() ); + } + + Reference< XStatement > stmt = extractConnectionFromStatement(m_owner)->createStatement(); + DisposeGuard dispGuard( stmt ); + OUStringBuffer buf( 128 ); + buf.appendAscii( "DELETE FROM " ); + bufferQuoteQualifiedIdentifier( buf, m_schema, m_table ); + buf.appendAscii( " " ); + buf.append( buildWhereClause() ); + + stmt->executeUpdate( buf.makeStringAndClear() ); + + // reflect the changes ! + for( int i = m_row + 1; i < m_row ; i ++ ) + { + m_data[i-1] = m_data[i]; + } + m_rowCount --; + m_data.realloc( m_rowCount ); + } + +void UpdateableResultSet::cancelRowUpdates( ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + m_updateableField = UpdateableFieldVector(); +} + +void UpdateableResultSet::moveToInsertRow( ) throw (SQLException, RuntimeException) +{ + m_insertRow = true; +} + +void UpdateableResultSet::moveToCurrentRow( ) throw (SQLException, RuntimeException) +{ + m_insertRow = false; +} + +void UpdateableResultSet::checkUpdate( sal_Int32 columnIndex) +{ + checkColumnIndex( columnIndex ); + if( m_updateableField.empty() ) + m_updateableField = UpdateableFieldVector( m_fieldCount ); + m_updateableField[columnIndex-1].isTouched = true; +} + +void UpdateableResultSet::updateNull( sal_Int32 columnIndex ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkUpdate( columnIndex ); + m_updateableField[columnIndex-1].value = Any(); +} + +void UpdateableResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkUpdate( columnIndex ); + + Statics &st = getStatics(); + if( x ) + m_updateableField[columnIndex-1].value <<= ( x ? st.TRUE : st.FALSE ); + +} + +void UpdateableResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw (SQLException, RuntimeException) +{ + updateInt(columnIndex,x); +} + +void UpdateableResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw (SQLException, RuntimeException) +{ + updateInt( columnIndex, x ); +} + +void UpdateableResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw (SQLException, RuntimeException) +{ + updateLong( columnIndex, x ); +// MutexGuard guard( m_refMutex->mutex ); +// checkClosed(); +// checkUpdate( columnIndex ); + +// m_updateableField[columnIndex-1].value <<= OUString::valueOf( x ); + +} + +void UpdateableResultSet::updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkUpdate( columnIndex ); + +// OStringBuffer buf( 20 ); +// buf.append( "'" ); +// buf.append( (sal_Int64) x ); +// buf.append( "'" ); + m_updateableField[columnIndex-1].value <<= OUString::valueOf( x ); +} + +void UpdateableResultSet::updateFloat( sal_Int32 columnIndex, float x ) throw (SQLException, RuntimeException) +{ + + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkUpdate( columnIndex ); + + m_updateableField[columnIndex-1].value <<= OUString::valueOf( x ); +} + +void UpdateableResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkUpdate( columnIndex ); + + m_updateableField[columnIndex-1].value <<= OUString::valueOf( x ); +} + +void UpdateableResultSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkUpdate( columnIndex ); + + m_updateableField[columnIndex-1].value <<= x; +} + +void UpdateableResultSet::updateBytes( sal_Int32 columnIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) throw (SQLException, RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + checkClosed(); + checkUpdate( columnIndex ); + + size_t len; + unsigned char * escapedString = + PQescapeBytea( (unsigned char *)x.getConstArray(), x.getLength(), &len); + if( ! escapedString ) + { + throw SQLException( + ASCII_STR("pq_preparedstatement.setBytes: Error during converting bytesequence to an SQL conform string" ), + *this, OUString(), 1, Any() ); + } +// buf.append( (const sal_Char *)escapedString, len -1 ); + + m_updateableField[columnIndex-1].value <<= + OUString( (sal_Char*) escapedString, len, RTL_TEXTENCODING_ASCII_US ); + free( escapedString ); +} + +void UpdateableResultSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw (SQLException, RuntimeException) +{ + updateString( columnIndex, date2String( x ) ); +} + +void UpdateableResultSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw (SQLException, RuntimeException) +{ + updateString( columnIndex, time2String( x ) ); +} + +void UpdateableResultSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw (SQLException, RuntimeException) +{ + updateString( columnIndex, dateTime2String( x ) ); +} + +void UpdateableResultSet::updateBinaryStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw (SQLException, RuntimeException) +{ +} + +void UpdateableResultSet::updateCharacterStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw (SQLException, RuntimeException) +{ +} + +void UpdateableResultSet::updateObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x ) throw (SQLException, RuntimeException) +{ +} + +void UpdateableResultSet::updateNumericObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x, sal_Int32 scale ) throw (SQLException, RuntimeException) +{ +} + + +::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > UpdateableResultSet::getMetaData( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + return m_meta; +} + +Sequence< Type > UpdateableResultSet::getStaticTypes( bool updateable ) + throw( com::sun::star::uno::RuntimeException ) +{ + if( updateable ) + { + cppu::OTypeCollection collection( + getCppuType( (Reference< XResultSetUpdate> *) 0 ), + getCppuType( (Reference< XRowUpdate> *) 0 ), +// getCppuType( (Reference< com::sun::star::sdbcx::XRowLocate > *) 0 ), + getStaticTypes( false /* updateable */ ) ); + return collection.getTypes(); + } + else + { + cppu::OTypeCollection collection( + getCppuType( (Reference< XResultSet> *) 0 ), + getCppuType( (Reference< XResultSetMetaDataSupplier> *) 0 ), + getCppuType( (Reference< XRow> *) 0 ), + getCppuType( (Reference< XColumnLocate> *) 0 ), + getCppuType( (Reference< XCloseable> *) 0 ), + getCppuType( (Reference< XPropertySet >*) 0 ), + getCppuType( (Reference< XFastPropertySet > *) 0 ), + getCppuType( (Reference< XMultiPropertySet > *) 0 ), + getCppuType( (const Reference< com::sun::star::lang::XComponent > *)0 ), // OComponentHelper + getCppuType( (const Reference< com::sun::star::lang::XTypeProvider > *)0 ), + getCppuType( (const Reference< com::sun::star::uno::XAggregation > *)0 ), + getCppuType( (const Reference< com::sun::star::uno::XWeak > *)0 ) ); + return collection.getTypes(); + } +} + +} diff --git connectivity/source/drivers/postgresql/pq_updateableresultset.hxx connectivity/source/drivers/postgresql/pq_updateableresultset.hxx new file mode 100644 index 0000000..0154bb7 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_updateableresultset.hxx @@ -0,0 +1,118 @@ +#include "pq_sequenceresultset.hxx" +#include "pq_resultsetmetadata.hxx" + +#include +#include + +namespace pq_sdbc_driver +{ + +struct UpdateableField +{ + UpdateableField( ) + : isTouched(false) + {} + com::sun::star::uno::Any value; + bool isTouched; +}; + +typedef ::std::vector< UpdateableField , Allocator< UpdateableField > > UpdateableFieldVector; + +class UpdateableResultSet : + public SequenceResultSet, + public com::sun::star::sdbc::XResultSetUpdate, + public com::sun::star::sdbc::XRowUpdate +{ + ConnectionSettings **m_ppSettings; + rtl::OUString m_schema; + rtl::OUString m_table; + com::sun::star::uno::Sequence< rtl::OUString > m_primaryKey; + UpdateableFieldVector m_updateableField; + com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSetMetaData > m_meta; + bool m_insertRow; + +protected: + UpdateableResultSet( + const ::rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner, + const com::sun::star::uno::Sequence< rtl::OUString > &colNames, + const com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< com::sun::star::uno::Any > > &data, + ConnectionSettings **ppSettings, + const rtl::OUString &schema, + const rtl::OUString &table, + const com::sun::star::uno::Sequence< ::rtl::OUString > &primaryKey) + : SequenceResultSet( mutex, owner, colNames, data, (*ppSettings)->tc ), + m_insertRow( false ), + m_primaryKey( primaryKey ), + m_table( table ), + m_schema( schema ), + m_ppSettings( ppSettings ) + { + } + + rtl::OUString buildWhereClause(); + void checkUpdate( sal_Int32 column ); + +public: + static com::sun::star::uno::Reference< com::sun::star::sdbc::XCloseable > createFromPGResultSet( + const ::rtl::Reference< RefCountedMutex > & mutex, + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner, + ConnectionSettings **ppSettings, + PGresult *result, + const rtl::OUString &schema, + const rtl::OUString &table, + const com::sun::star::uno::Sequence< ::rtl::OUString > &primaryKey ); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { SequenceResultSet::acquire(); } + virtual void SAL_CALL release() throw() { SequenceResultSet::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XTypeProvider + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XResultSetUpdate + virtual void SAL_CALL insertRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deleteRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL cancelRowUpdates( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL moveToInsertRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL moveToCurrentRow( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XRowUpdate + virtual void SAL_CALL updateNull( sal_Int32 columnIndex ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateFloat( sal_Int32 columnIndex, float x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateDouble( sal_Int32 columnIndex, double x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateBytes( sal_Int32 columnIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateBinaryStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateCharacterStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateNumericObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x, sal_Int32 scale ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + +public: // XResultSetMetaDataSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL getMetaData( ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + + static com::sun::star::uno::Sequence< com::sun::star::uno::Type > getStaticTypes( bool updateable ) + throw( com::sun::star::uno::RuntimeException ); + +}; + + + +} diff --git connectivity/source/drivers/postgresql/pq_xbase.cxx connectivity/source/drivers/postgresql/pq_xbase.cxx new file mode 100644 index 0000000..f1fbf46 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xbase.cxx @@ -0,0 +1,279 @@ +/************************************************************************* + * + * $RCSfile: pq_xbase.cxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:26:59 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include +#include + +#include "pq_tools.hxx" +#include "pq_xbase.hxx" + +using osl::MutexGuard; + +using com::sun::star::uno::Any; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::beans::Property; +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::XMultiPropertySet; +using com::sun::star::beans::XFastPropertySet; +using com::sun::star::beans::XPropertySet; + +namespace pq_sdbc_driver +{ + +ReflectionBase::ReflectionBase( + const ::rtl::OUString &implName, + const ::com::sun::star::uno::Sequence< rtl::OUString > &supportedServices, + const ::rtl::Reference< RefCountedMutex > refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > &conn, + ConnectionSettings *pSettings, + cppu::IPropertyArrayHelper & props /* must survive this object !*/ ) + : OComponentHelper( refMutex->mutex ), + OPropertySetHelper( OComponentHelper::rBHelper ), + m_implName( implName ), + m_supportedServices( supportedServices ), + m_refMutex( refMutex ), + m_conn( conn ), + m_pSettings( pSettings ), + m_propsDesc( props ), + m_values( props.getProperties().getLength() ) +{} + +cppu::IPropertyArrayHelper & ReflectionBase::getInfoHelper() +{ + return m_propsDesc; +} + +sal_Bool ReflectionBase::convertFastPropertyValue( + ::com::sun::star::uno::Any & rConvertedValue, + ::com::sun::star::uno::Any & rOldValue, + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::lang::IllegalArgumentException) +{ + + rOldValue = m_values[nHandle]; + rConvertedValue = rValue; // TODO !!! implement correct conversion ! + m_values[nHandle] = rValue; + return sal_True; +} + +void ReflectionBase::setPropertyValue_NoBroadcast_public( + const rtl::OUString & name, const com::sun::star::uno::Any & value ) +{ + sal_Int32 nHandle = m_propsDesc.getHandleByName( name ); + if( -1 == nHandle ) + { + rtl::OUStringBuffer buf(128); + buf.appendAscii( "Unkown property '" ); + buf.append( name ); + buf.appendAscii( "' in " ); + buf.append( m_implName ); + throw com::sun::star::uno::RuntimeException( buf.makeStringAndClear() , *this ); + } + setFastPropertyValue_NoBroadcast( nHandle , value ); +} + +void ReflectionBase::setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::uno::Exception) +{ +// rtl::OUString s; +// rValue >>= s; +// printf( "setting value (handle %d):%s\n" , +// nHandle, rtl::OUStringToOString(s, RTL_TEXTENCODING_ASCII_US).getStr() ); + m_values[nHandle] = rValue; +} + +void ReflectionBase::getFastPropertyValue( + ::com::sun::star::uno::Any& rValue, + sal_Int32 nHandle ) const +{ + rValue = m_values[nHandle]; +// rtl::OUString s; +// rValue >>= s; +// printf( "getting value (handle %d):%s\n" , +// nHandle, rtl::OUStringToOString(s, RTL_TEXTENCODING_ASCII_US).getStr() ); + +} + +Reference < ::com::sun::star::beans::XPropertySetInfo > ReflectionBase::getPropertySetInfo() + throw(com::sun::star::uno::RuntimeException) +{ + return OPropertySetHelper::createPropertySetInfo( m_propsDesc ); +} + +rtl::OUString ReflectionBase::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return m_implName; +} + +sal_Bool ReflectionBase::supportsService(const rtl::OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException) +{ + for( int i = 0 ; i < m_supportedServices.getLength() ; i ++ ) + if( m_supportedServices[i] == ServiceName ) + return sal_True; + return sal_False; +} + +Sequence< rtl::OUString > ReflectionBase::getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException) +{ + return m_supportedServices; +} + + +Sequence< com::sun::star::uno::Type > ReflectionBase::getTypes() + throw( com::sun::star::uno::RuntimeException ) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + static cppu::OTypeCollection collection( + getCppuType( (Reference< XPropertySet >*) 0 ), + getCppuType( (Reference< XFastPropertySet > *) 0 ), + getCppuType( (Reference< XMultiPropertySet > *) 0 ), + getCppuType( (Reference< com::sun::star::lang::XServiceInfo > *) 0 ), + getCppuType( (Reference< com::sun::star::sdbcx::XDataDescriptorFactory > *) 0 ), + getCppuType( (Reference< com::sun::star::container::XNamed > *) 0 ), + OComponentHelper::getTypes()); + return collection.getTypes(); +} + + +com::sun::star::uno::Any ReflectionBase::queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException) +{ + Any ret; + ret = OComponentHelper::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< com::sun::star::beans::XPropertySet * > ( this ), + static_cast< com::sun::star::beans::XMultiPropertySet * > ( this ), + static_cast< com::sun::star::lang::XServiceInfo * > ( this ), + static_cast< com::sun::star::beans::XFastPropertySet * > ( this ) , + static_cast< com::sun::star::sdbcx::XDataDescriptorFactory * > ( this ), + static_cast< com::sun::star::container::XNamed * > ( this ) ); + return ret; + +} + +Sequence< sal_Int8> ReflectionBase::getImplementationId() throw( RuntimeException ) +{ + static cppu::OImplementationId *pId; + if( ! pId ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( ! pId ) + { + static cppu::OImplementationId id(sal_False); + pId = &id; + } + } + return pId->getImplementationId(); +} + +void ReflectionBase::copyValuesFrom( const Reference< XPropertySet > & set ) +{ + Reference< XPropertySetInfo > info = set->getPropertySetInfo(); + if( info.is () ) + { + Reference< XPropertySetInfo > myPropInfo = getPropertySetInfo(); + + Sequence< Property > props = info->getProperties(); + for( int i = 0 ; i < props.getLength() ; i ++ ) + { + if( myPropInfo->hasPropertyByName( props[i].Name ) ) + setPropertyValue_NoBroadcast_public( + props[i].Name, set->getPropertyValue( props[i].Name ) ); + } + } +} + +::rtl::OUString ReflectionBase::getName( ) throw (::com::sun::star::uno::RuntimeException) +{ + Statics & st = getStatics(); + if( getInfoHelper().hasPropertyByName( st.SCHEMA_NAME ) ) + return concatQualified( + extractStringProperty( this, getStatics().SCHEMA_NAME ), + extractStringProperty( this, getStatics().NAME ) ); + else + return extractStringProperty( this, getStatics().NAME ); +} + + +void ReflectionBase::setName( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException) +{ + throw RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "pq_sdbc::ReflectionBase::setName not implemented" ) ), + *this ); + //setPropertyValue( getStatics().NAME , makeAny( aName ) ); +} + + +} diff --git connectivity/source/drivers/postgresql/pq_xbase.hxx connectivity/source/drivers/postgresql/pq_xbase.hxx new file mode 100644 index 0000000..f05c352 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xbase.hxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * $RCSfile: pq_xbase.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:26:59 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_REFL_BASE_HXX_ +#define _PQ_REFL_BASE_HXX_ +#include +#include + +#include +#include + +#include "pq_xcontainer.hxx" + +namespace pq_sdbc_driver +{ + +class ReflectionBase : + public cppu::OComponentHelper, + public cppu::OPropertySetHelper, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::sdbcx::XDataDescriptorFactory, + public com::sun::star::container::XNamed +{ +protected: + const rtl::OUString m_implName; + const ::com::sun::star::uno::Sequence< rtl::OUString > m_supportedServices; + ::rtl::Reference< RefCountedMutex > m_refMutex; + ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > m_conn; + ConnectionSettings *m_pSettings; + cppu::IPropertyArrayHelper & m_propsDesc; + com::sun::star::uno::Sequence< com::sun::star::uno::Any > m_values; +public: + ReflectionBase( + const ::rtl::OUString &implName, + const ::com::sun::star::uno::Sequence< rtl::OUString > &supportedServices, + const ::rtl::Reference< RefCountedMutex > refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > &conn, + ConnectionSettings *pSettings, + cppu::IPropertyArrayHelper & props /* must survive this object !*/ ); + +public: + void copyValuesFrom( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > &set ); + +public: // for initialization purposes only, not exported via an interface ! + void setPropertyValue_NoBroadcast_public( + const rtl::OUString & name, const com::sun::star::uno::Any & value ); + +public: //XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // OPropertySetHelper + virtual cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper(); + + virtual sal_Bool SAL_CALL convertFastPropertyValue( + ::com::sun::star::uno::Any & rConvertedValue, + ::com::sun::star::uno::Any & rOldValue, + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::lang::IllegalArgumentException); + + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::uno::Exception); + + virtual void SAL_CALL getFastPropertyValue( + ::com::sun::star::uno::Any& rValue, + sal_Int32 nHandle ) const; + + // XPropertySet + ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw(com::sun::star::uno::RuntimeException); + +public: // XServiceInfo + virtual rtl::OUString SAL_CALL getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService(const rtl::OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException); + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException) = 0; + +public: // XNamed + virtual ::rtl::OUString SAL_CALL getName( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_xcolumn.cxx connectivity/source/drivers/postgresql/pq_xcolumn.cxx new file mode 100644 index 0000000..7fb6c62 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xcolumn.cxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * $RCSfile: pq_xcolumn.cxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:26:59 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include "pq_xcolumn.hxx" + +using com::sun::star::uno::Any; +using com::sun::star::uno::Reference; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Type; +using com::sun::star::uno::Sequence; + +using com::sun::star::beans::XPropertySet; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +Column::Column( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings) + : ReflectionBase( + getStatics().refl.column.implName, + getStatics().refl.column.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.column.pProps ) +{} + +Reference< XPropertySet > Column::createDataDescriptor( ) throw (RuntimeException) +{ + ColumnDescriptor * pColumn = new ColumnDescriptor( + m_refMutex, m_conn, m_pSettings ); + pColumn->copyValuesFrom( this ); + return Reference< XPropertySet > ( pColumn ); +} + +ColumnDescriptor::ColumnDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings) + : ReflectionBase( + getStatics().refl.columnDescriptor.implName, + getStatics().refl.columnDescriptor.serviceNames, + refMutex, + connection, + pSettings, + *getStatics().refl.columnDescriptor.pProps ) +{} + +Reference< XPropertySet > ColumnDescriptor::createDataDescriptor( ) throw (RuntimeException) +{ + ColumnDescriptor * pColumn = new ColumnDescriptor( + m_refMutex, m_conn, m_pSettings ); + pColumn->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pColumn ); +} + + + + + +} diff --git connectivity/source/drivers/postgresql/pq_xcolumn.hxx connectivity/source/drivers/postgresql/pq_xcolumn.hxx new file mode 100644 index 0000000..00b3b7b --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xcolumn.hxx @@ -0,0 +1,108 @@ +/************************************************************************* + * + * $RCSfile: pq_xcolumn.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:26:59 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_COLUMN_HXX_ +#define _PQ_COLUMN_HXX_ + +#include +#include + +#include +#include + +#include "pq_connection.hxx" +#include "pq_xbase.hxx" + +namespace pq_sdbc_driver +{ + +class Column : public ReflectionBase +{ +public: + Column( const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +}; + +class ColumnDescriptor : public ReflectionBase +{ +public: + ColumnDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +}; + + +} + + +#endif diff --git connectivity/source/drivers/postgresql/pq_xcolumns.cxx connectivity/source/drivers/postgresql/pq_xcolumns.cxx new file mode 100644 index 0000000..a424e3e --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xcolumns.cxx @@ -0,0 +1,616 @@ +/************************************************************************* + * + * $RCSfile: pq_xcolumns.cxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2004/08/29 08:33:30 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include "pq_xcolumns.hxx" +#include "pq_xcolumn.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::XPropertyChangeListener; +using com::sun::star::beans::PropertyChangeEvent; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::container::NoSuchElementException; +using com::sun::star::lang::WrappedTargetException; + +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XDatabaseMetaData; +using com::sun::star::sdbc::SQLException; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +static Any isCurrency( const rtl::OUString & typeName ) +{ + sal_Bool b = typeName.equalsIgnoreAsciiCaseAscii( "money" ); + return Any( &b, getBooleanCppuType() ); +} + +// static sal_Bool isAutoIncrement8( const rtl::OUString & typeName ) +// { +// return typeName.equalsIgnoreAsciiCaseAscii( "serial8" ) || +// typeName.equalsIgnoreAsciiCaseAscii( "bigserial" ); +// } + +static Any isAutoIncrement( const rtl::OUString & defaultValue ) +{ + sal_Bool ret = sal_False; + + ret = defaultValue.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "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, getBooleanCppuType() ); +} + +Columns::Columns( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName) + : Container( refMutex, origin, pSettings, ASCII_STR( "COLUMN" ) ), + m_schemaName( schemaName ), + m_tableName( tableName ) +{} + +Columns::~Columns() +{} + +rtl::OUString columnMetaData2SDBCX( + ReflectionBase *pBase, const com::sun::star::uno::Reference< com::sun::star::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_attribure.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, makeAny( name ) ); + + pBase->setPropertyValue_NoBroadcast_public( + st.TYPE, makeAny( xRow->getInt( DATA_TYPE ) ) ); + + pBase->setPropertyValue_NoBroadcast_public( + st.TYPE_NAME, makeAny( typeName ) ); + + pBase->setPropertyValue_NoBroadcast_public( + st.PRECISION, makeAny( xRow->getInt( COLUMN_SIZE ) ) ); + + pBase->setPropertyValue_NoBroadcast_public( + st.SCALE, makeAny( xRow->getInt( DECIMAL_DIGITS ) ) ); + + pBase->setPropertyValue_NoBroadcast_public( + st.IS_NULLABLE, makeAny( xRow->getInt( IS_NULLABLE ) ) ); + + pBase->setPropertyValue_NoBroadcast_public( + st.DEFAULT_VALUE, makeAny( 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, makeAny( xRow->getString( DESCRIPTION ) ) ); + + + // maybe a better criterium 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::WeakImplHelper1< XPropertyChangeListener > +// { +// ::rtl::Reference< RefCountedMutex > m_refMutex; +// ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > m_connection; +// ConnectionSettings *m_pSettings; +// rtl::OUString m_schema; +// rtl::OUString m_table; +// rtl::OUString m_column; + +// public: +// CommentChanger( +// const ::rtl::Reference< RefCountedMutex > & refMutex, +// const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, +// ConnectionSettings *pSettings, +// const rtl::OUString & schema, +// const rtl::OUString & table, +// const rtl::OUString & column ) : +// m_refMutex( refMutex ), +// m_connection( connection ), +// m_pSettings( pSettings ), +// m_schema ( schema ), +// m_table ( table ), +// m_column ( column ) +// {} + + +// // Methods +// virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException) +// { +// osl::MutexGuard guard( m_refMutex->mutex ); +// m_connection.clear(); +// } +// // Methods +// virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw (::com::sun::star::uno::RuntimeException) +// { +// osl::MutexGuard guard( m_refMutex->mutex ); +// OUStringBuffer buf( 128 ); +// OUString comment; +// evt.NewValue >>= comment; +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "COMMENT ON COLUMN" ) ); +// bufferQuoteQualifiedIdentifier( buf, m_schema, m_table , m_column ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "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() + throw (::com::sun::star::uno::RuntimeException) +{ + try + { + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + rtl::OStringBuffer buf; + buf.append( "sdbcx.Columns get refreshed for table " ); + buf.append( OUStringToOString( m_schemaName, m_pSettings->encoding ) ); + buf.append( "." ); + buf.append( OUStringToOString( m_tableName, m_pSettings->encoding ) ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() ); + } + osl::MutexGuard guard( m_refMutex->mutex ); + + 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; + + std::vector< Any, Allocator< Any> > vec; + sal_Int32 columnIndex = 0; + while( rs->next() ) + { + Column * pColumn = + new Column( m_refMutex, m_origin, m_pSettings ); + Reference< com::sun::star::beans::XPropertySet > prop = pColumn; + + OUString name = columnMetaData2SDBCX( pColumn, xRow ); +// pColumn->addPropertyChangeListener( +// st.HELP_TEXT, +// new CommentChanger( +// m_refMutex, +// m_origin, +// m_pSettings, +// m_schemaName, +// m_tableName, +// name ) ); + + vec.push_back( makeAny( prop ) ); + map[ name ] = columnIndex; + columnIndex ++; + } + m_values = Sequence< com::sun::star::uno::Any > ( & vec[0] , vec.size() ); + m_name2index.swap( map ); + } + catch ( com::sun::star::sdbc::SQLException & e ) + { + throw RuntimeException( e.Message , e.Context ); + } + fire( RefreshedBroadcaster( *this ) ); +} + + +void alterColumnByDescriptor( + const OUString & schemaName, + const OUString & tableName, + rtl_TextEncoding encoding, + const Reference< XStatement > &stmt, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > & past, + const com::sun::star::uno::Reference< com::sun::star::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.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Can't move column " ) ); +// buf.append( extractStringProperty( past, st.COLUMN_NAME ) ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " from table " ) ); +// buf.append( extractStringProperty( past, st.TABLE_NAME ) ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " to table " ) ); +// buf.append( extractStringProperty( past, st.TABLE_NAME ) ); +// throw SQLException( buf.makeStringAndClear(), Reference< XInterface > () ); +// } + +// 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.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); + bufferQuoteQualifiedIdentifier( buf, schemaName, tableName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ADD COLUMN" ) ); + bufferQuoteIdentifier( buf, futureColumnName ); + buf.append( futureTypeName ); + transaction.executeUpdate( buf.makeStringAndClear() ); + } + else + { + if( pastTypeName != futureTypeName ) + { + throw RuntimeException( + ASCII_STR( "Can't modify column types, drop the column and create a new one" ), + Reference< XInterface > () ); + } + + if( pastColumnName != futureColumnName ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); + bufferQuoteQualifiedIdentifier( buf, schemaName, tableName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "RENAME COLUMN" ) ); + bufferQuoteIdentifier( buf, pastColumnName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "TO" ) ); + bufferQuoteIdentifier( buf, futureColumnName ); + transaction.executeUpdate( buf.makeStringAndClear() ); + } + } + + OUString futureDefaultValue = extractStringProperty( future, st.DEFAULT_VALUE ); + OUString pastDefaultValue = extractStringProperty( past, st.DEFAULT_VALUE ); + if( futureDefaultValue != pastDefaultValue ) + { + buf = OUStringBuffer( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); + bufferQuoteQualifiedIdentifier( buf, schemaName, tableName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER COLUMN" ) ); + bufferQuoteIdentifier( buf, futureColumnName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SET DEFAULT " ) ); + // default value is not quoted, caller needs to quote himself (otherwise + // how to pass e.g. nextval('something' ) ???? + buf.append( 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 = OUStringBuffer( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); + bufferQuoteQualifiedIdentifier( buf, schemaName, tableName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER COLUMN" ) ); + bufferQuoteIdentifier( buf, futureColumnName ); + if( futureNullable == com::sun::star::sdbc::ColumnValue::NO_NULLS ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SET" ) ); + } + else + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "DROP" ) ); + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " 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 = OUStringBuffer( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "COMMENT ON COLUMN" ) ); + bufferQuoteQualifiedIdentifier( buf, schemaName, tableName , futureColumnName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "IS " ) ); + bufferQuoteConstant( buf, futureComment,encoding); + transaction.executeUpdate( buf.makeStringAndClear() ); + } + transaction.commit(); +} + +void Columns::appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& future ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + Statics & st = getStatics(); + Reference< XPropertySet > past = createDataDescriptor(); + past->setPropertyValue( st.IS_NULLABLE, makeAny( com::sun::star::sdbc::ColumnValue::NULLABLE ) ); + alterColumnByDescriptor( + m_schemaName, m_tableName, m_pSettings->encoding, m_origin->createStatement() , past, future ); + + refresh(); +} + +// void Columns::dropByName( const ::rtl::OUString& elementName ) +// throw (::com::sun::star::sdbc::SQLException, +// ::com::sun::star::container::NoSuchElementException, +// ::com::sun::star::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 com::sun::star::container::NoSuchElementException( +// buf.makeStringAndClear(), *this ); +// } +// dropByIndex( ii->second ); +// } + +void Columns::dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + if( index < 0 || index >= m_values.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "COLUMNS: Index out of range (allowed 0 to " ); + buf.append((sal_Int32)(m_values.getLength() -1) ); + buf.appendAscii( ", got " ); + buf.append( index ); + buf.appendAscii( ")" ); + throw com::sun::star::lang::IndexOutOfBoundsException( + buf.makeStringAndClear(), *this ); + } + + Reference< XPropertySet > set; + m_values[index] >>= set; + Statics &st = getStatics(); + OUString name; + set->getPropertyValue( st.NAME ) >>= name; + + OUStringBuffer update( 128 ); + update.appendAscii( "ALTER TABLE ONLY"); + bufferQuoteQualifiedIdentifier( update, m_schemaName, m_tableName ); + update.appendAscii( "DROP COLUMN" ); + bufferQuoteIdentifier( update, name ); + Reference< XStatement > stmt = m_origin->createStatement( ); + DisposeGuard disposeIt( stmt ); + stmt->executeUpdate( update.makeStringAndClear() ); + + Container::dropByIndex( index ); +} + + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Columns::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new ColumnDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +Reference< com::sun::star::container::XNameAccess > Columns::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + Columns **ppColumns) +{ + *ppColumns = new Columns( + refMutex, origin, pSettings, schemaName, tableName ); + Reference< com::sun::star::container::XNameAccess > ret = *ppColumns; + (*ppColumns)->refresh(); + + return ret; +} + + +//_____________________________________________________________________________________ +ColumnDescriptors::ColumnDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ) + : Container( refMutex, origin, pSettings, ASCII_STR( "COLUMN-DESCRIPTOR" ) ) +{} + + +Reference< ::com::sun::star::beans::XPropertySet > ColumnDescriptors::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new ColumnDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +} diff --git connectivity/source/drivers/postgresql/pq_xcolumns.hxx connectivity/source/drivers/postgresql/pq_xcolumns.hxx new file mode 100644 index 0000000..3f5301a --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xcolumns.hxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * $RCSfile: pq_xcolumns.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:00 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_COLUMNS_HXX_ +#define _PQ_COLUMNS_HXX_ + +#include "pq_xcontainer.hxx" +#include "pq_xbase.hxx" + +namespace pq_sdbc_driver +{ + +void alterColumnByDescriptor( + const rtl::OUString & schemaName, + const rtl::OUString & tableName, + rtl_TextEncoding encoding, + const com::sun::star::uno::Reference< com::sun::star::sdbc::XStatement > &stmt, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > & past, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > & future); + +rtl::OUString columnMetaData2SDBCX( + ReflectionBase *pBase, const com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > &xRow ); + +class Columns : public Container +{ + rtl::OUString m_schemaName; + rtl::OUString m_tableName; + +public: // instances Columns 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + Columns **pColumns); + +protected: + Columns( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName); + + + virtual ~Columns(); + +public: // XAppend + virtual void SAL_CALL appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +// public: // XDrop +// virtual void SAL_CALL dropByName( const ::rtl::OUString& elementName ) +// throw (::com::sun::star::sdbc::SQLException, +// ::com::sun::star::container::NoSuchElementException, +// ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // XRefreshable + virtual void SAL_CALL refresh( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); +}; + + +class ColumnDescriptors : public Container +{ +public: + ColumnDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_xcontainer.cxx connectivity/source/drivers/postgresql/pq_xcontainer.cxx new file mode 100644 index 0000000..6e0126a --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xcontainer.cxx @@ -0,0 +1,514 @@ +/************************************************************************* + * + * $RCSfile: pq_xcontainer.cxx,v $ + * + * $Revision: 1.1.2.5 $ + * + * last change: $Author: jbu $ $Date: 2007/01/07 13:50:38 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include + + +#include + +#include "pq_xcontainer.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::beans::XPropertySet; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::container::NoSuchElementException; +using com::sun::star::container::XEnumeration; +using com::sun::star::container::XContainerListener; +using com::sun::star::container::ContainerEvent; +using com::sun::star::lang::IndexOutOfBoundsException; +using com::sun::star::lang::XEventListener; + +using com::sun::star::lang::WrappedTargetException; + +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbcx::XDataDescriptorFactory; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + + +class ReplacedBroadcaster : public EventBroadcastHelper +{ + ContainerEvent m_event; +public: + ReplacedBroadcaster( + const Reference< XInterface > & source, + const rtl::OUString & name, + const Any & newElement, + const rtl::OUString & oldElement ) : + m_event( source, makeAny( name ), newElement, makeAny(oldElement) ) + {} + + virtual void fire( XEventListener * listener ) const + { + ((XContainerListener*)listener)->elementReplaced( m_event ); + } + virtual Type getType() const + { + return getCppuType( (Reference< XContainerListener > *)0 ); + } +}; + +class InsertedBroadcaster : public EventBroadcastHelper +{ +public: + ContainerEvent m_event; + InsertedBroadcaster( + const Reference< XInterface > & source, + const rtl::OUString & name, + const Any & newElement ) : + m_event( source, makeAny( name ), newElement, Any() ) + {} + + virtual void fire( XEventListener * listener ) const + { + ((XContainerListener*)listener)->elementInserted( m_event ); + } + + virtual Type getType() const + { + return getCppuType( (Reference< XContainerListener > *)0 ); + } +}; + +class RemovedBroadcaster : public EventBroadcastHelper +{ +public: + ContainerEvent m_event; + RemovedBroadcaster( + const Reference< XInterface > & source, + const rtl::OUString & name) : + m_event( source, makeAny( name ), Any(), Any() ) + {} + + virtual void fire( XEventListener * listener ) const + { + ((XContainerListener*)listener)->elementRemoved( m_event ); + } + + virtual Type getType() const + { + return getCppuType( (Reference< XContainerListener > *)0 ); + } +}; + +Container::Container( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const ::rtl::OUString &type) + : ContainerBase( refMutex->mutex ), + m_refMutex( refMutex ), + m_pSettings( pSettings ), + m_origin( origin ), + m_type( type ) +{ +} + +Any Container::getByName( const ::rtl::OUString& aName ) + throw (NoSuchElementException,WrappedTargetException,RuntimeException) +{ + String2IntMap::const_iterator ii = m_name2index.find( aName ); + if( ii == m_name2index.end() ) + { + OUStringBuffer buf(128); + buf.appendAscii( "Element " ); + buf.append( aName ); + buf.appendAscii( " unknown in " ); + buf.append( m_type ); + buf.appendAscii( "-Container" ); + throw NoSuchElementException( buf.makeStringAndClear() , *this ); + } + OSL_ASSERT( ii->second >= 0 && ii->second < m_values.getLength() ); + return m_values[ ii->second ]; +} + +Sequence< OUString > Container::getElementNames( ) + throw (::com::sun::star::uno::RuntimeException) +{ + Sequence< OUString > ret( m_values.getLength() ); + for( String2IntMap::const_iterator ii = m_name2index.begin(); + ii != m_name2index.end() ; + ++ ii ) + { + // give element names in index order ! + ret[ii->second] = ii->first; +// ret[i] = ii->first; + } + return ret; +} + +sal_Bool Container::hasByName( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException) +{ + return m_name2index.find( aName ) != m_name2index.end(); +} + // Methods +Type Container::getElementType( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return Type(); +} + +sal_Bool Container::hasElements( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return ! m_name2index.empty(); +} + +Any Container::getByIndex( sal_Int32 Index ) + throw (::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + if( Index < 0 || Index >= m_values.getLength() ) + { + OUStringBuffer buf(128); + buf.appendAscii( "Index " ); + buf.append( Index ); + buf.appendAscii(" out of range for " ); + buf.append( m_type ); + buf.appendAscii("-Container, expected 0 <= x <= " ); + buf.append( (sal_Int32 ) (m_values.getLength() -1)); + throw IndexOutOfBoundsException( buf.makeStringAndClear(), *this ); + } + return m_values[Index]; +} + +sal_Int32 Container::getCount() + throw (::com::sun::star::uno::RuntimeException) +{ + return m_values.getLength(); +} + + +class ContainerEnumeration : public ::cppu::WeakImplHelper1< XEnumeration > +{ + com::sun::star::uno::Sequence< com::sun::star::uno::Any > m_vec; + sal_Int32 m_index; +public: + ContainerEnumeration( const com::sun::star::uno::Sequence< com::sun::star::uno::Any > &vec ) + : m_vec( vec ), + m_index( -1 ) + {} + +public: + // XEnumeration + virtual sal_Bool SAL_CALL hasMoreElements( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL nextElement( ) + throw (::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + +}; + +sal_Bool ContainerEnumeration::hasMoreElements() + throw (::com::sun::star::uno::RuntimeException) +{ + return m_vec.getLength() > m_index +1; +} + +com::sun::star::uno::Any ContainerEnumeration::nextElement() + throw (::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + if( ! hasMoreElements() ) + { + throw NoSuchElementException( + ASCII_STR( "NoSuchElementException during enumeration" ), *this ); + } + m_index ++; + return m_vec[m_index]; +} + +Reference< XEnumeration > Container::createEnumeration( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return new ContainerEnumeration( m_values ); +} + +void Container::addRefreshListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener >& l ) + throw (::com::sun::star::uno::RuntimeException) +{ + rBHelper.addListener( getCppuType(&l) , l ); +} + +void Container::removeRefreshListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener >& l ) + throw (::com::sun::star::uno::RuntimeException) +{ + rBHelper.removeListener( getCppuType(&l) , l ); +} + +void Container::disposing() +{ + m_origin.clear(); +} + +void Container::rename( const rtl::OUString &oldName, const rtl::OUString &newName ) +{ + Any newValue; + { + osl::MutexGuard guard ( m_refMutex->mutex ); + String2IntMap::iterator ii = m_name2index.find( oldName ); + if( ii != m_name2index.end() ) + { + sal_Int32 nIndex = ii->second; + newValue = m_values[nIndex]; + m_name2index.erase( ii ); + m_name2index[ newName ] = nIndex; + newValue = m_values[nIndex]; + } + } + fire( ReplacedBroadcaster( *this, newName, newValue, oldName ) ); + fire( RefreshedBroadcaster( *this ) ); +} + +void Container::dropByName( const ::rtl::OUString& elementName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + 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 " ); + buf.append( m_type ); +// buf.appendAscii( " " ); +// buf.append( m_schemaName ); +// buf.appendAscii( "." ); +// buf.append( m_tableName ); + buf.appendAscii( " container, so it can't be dropped" ); + throw com::sun::star::container::NoSuchElementException( + buf.makeStringAndClear(), *this ); + } + dropByIndex( ii->second ); +} + +void Container::dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + if( index < 0 || index >= m_values.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "Index out of range (allowed 0 to " ); + buf.append((sal_Int32)(m_values.getLength() -1) ); + buf.appendAscii( ", got " ); + buf.append( index ); + buf.appendAscii( ") in " ); + buf.append( m_type ); + throw com::sun::star::lang::IndexOutOfBoundsException( + buf.makeStringAndClear(), *this ); + } + + OUString name; + for( String2IntMap::iterator ii = m_name2index.begin() ; + ii != m_name2index.end() ; + ++ ii ) + { + if( ii->second == index ) + { + name = ii->first; + m_name2index.erase( ii ); + break; + } + } + + Any oldElement = m_values[index]; + for( int i = index +1 ; i < m_values.getLength() ; i ++ ) + { + m_values[i-1] = m_values[i]; + + // I know, this is expensive, but don't want to maintain another map ... + for( String2IntMap::iterator ii = m_name2index.begin() ; + ii != m_name2index.end() ; + ++ ii ) + { + if( ii->second == i ) + { + ii->second = i-1; + break; + } + } + } + m_values.realloc( m_values.getLength() - 1 ); + + fire( RemovedBroadcaster( *this, name ) ); +} + +void Container::append( + const rtl::OUString & name, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw ( ::com::sun::star::container::ElementExistException ) + +{ + osl::MutexGuard guard( m_refMutex->mutex ); + + if( hasByName( name ) ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "a "); + buf.append( m_type ); + buf.appendAscii( " with name " ); + buf.append( name ); + buf.appendAscii( " already exists in this container" ); + throw com::sun::star::container::ElementExistException( + buf.makeStringAndClear() , *this ); + } + + int index = m_values.getLength(); + m_values.realloc( m_values.getLength() + 1 ); + m_values[index] = makeAny( descriptor ); + m_name2index[name] = index; + + fire( InsertedBroadcaster( *this, name, makeAny( descriptor ) ) ); +} + +void Container::appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + append( extractStringProperty( descriptor, getStatics().NAME ), descriptor ); +} + + +void Container::addContainerListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& l ) + throw (::com::sun::star::uno::RuntimeException) +{ + rBHelper.addListener( getCppuType(&l) , l ); +} + +void Container::removeContainerListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& l ) + throw (::com::sun::star::uno::RuntimeException) +{ + rBHelper.removeListener( getCppuType(&l) , l ); +} + + +void Container::fire( const EventBroadcastHelper &helper ) +{ + Reference< ::com::sun::star::util::XRefreshListener > l; + cppu::OInterfaceContainerHelper *container = rBHelper.getContainer( helper.getType() ); + if( container ) + { + cppu::OInterfaceIteratorHelper iterator( * container ); + while( iterator.hasMoreElements() ) + { + try + { + helper.fire( (XEventListener * ) iterator.next() ); + } + catch ( com::sun::star::uno::RuntimeException & e ) + { + OSL_ENSURE( 0, "exception catched" ); + // loose coupling, a runtime exception shall not break anything + // TODO: log away as warning ! + } + catch( com::sun::star::uno::Exception & e ) + { + OSL_ENSURE( 0, "exception from listener flying through" ); + throw; + } + } + } + +} + +} diff --git connectivity/source/drivers/postgresql/pq_xcontainer.hxx connectivity/source/drivers/postgresql/pq_xcontainer.hxx new file mode 100644 index 0000000..8aaffde --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xcontainer.hxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * $RCSfile: pq_xcontainer.hxx,v $ + * + * $Revision: 1.1.2.4 $ + * + * last change: $Author: jbu $ $Date: 2007/01/07 13:50:38 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_CONTAINER_HXX_ +#define _PQ_CONTAINER_HXX_ +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include "pq_connection.hxx" +#include "pq_statics.hxx" + +namespace pq_sdbc_driver +{ + +class EventBroadcastHelper +{ +public: + virtual void fire(com::sun::star::lang::XEventListener * listener) const = 0; + virtual com::sun::star::uno::Type getType() const = 0; + virtual ~EventBroadcastHelper(){}; +}; + +class RefreshedBroadcaster : public EventBroadcastHelper +{ + com::sun::star::lang::EventObject m_event; +public: + RefreshedBroadcaster(const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > & source ) : + m_event( source ) + {} + + virtual void fire( com::sun::star::lang::XEventListener * listener ) const + { + ((com::sun::star::util::XRefreshListener*)listener)->refreshed( m_event ); + } + + virtual com::sun::star::uno::Type getType() const + { + return getCppuType( + (com::sun::star::uno::Reference< com::sun::star::util::XRefreshListener > *)0 ); + } +}; + +typedef ::std::hash_map +< + rtl::OUString, + sal_Int32, + rtl::OUStringHash, + ::std::equal_to< rtl::OUString >, + Allocator< ::std::pair< const ::rtl::OUString , sal_Int32 > > +> String2IntMap; + +typedef ::cppu::WeakComponentImplHelper8 +< + com::sun::star::container::XNameAccess, + com::sun::star::container::XIndexAccess, + com::sun::star::container::XEnumerationAccess, + com::sun::star::sdbcx::XAppend, + com::sun::star::sdbcx::XDrop, + com::sun::star::util::XRefreshable, + com::sun::star::sdbcx::XDataDescriptorFactory, + com::sun::star::container::XContainer +> ContainerBase; + +class /* abstract */ Container : public ContainerBase +{ +protected: + ::rtl::Reference< RefCountedMutex > m_refMutex; + ConnectionSettings *m_pSettings; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_origin; + String2IntMap m_name2index; // maps the element name to an index + ::com::sun::star::uno::Sequence< com::sun::star::uno::Any > m_values; // contains the real values + ::rtl::OUString m_type; + +public: + Container( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const ::rtl::OUString & type // for exception messages + ); + +public: // XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) + throw (::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + +public: // XEnumerationAccess + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > + SAL_CALL createEnumeration( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XNameAccess + virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) + throw (::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException); + // Methods + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements( ) + throw (::com::sun::star::uno::RuntimeException); + + +public: // XAppend + // Must be overriden in Non-Descriptors. May be overriden in descriptors, when + // PropertySet.NAME != container name + virtual void SAL_CALL appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + + // helper method ! + void append( + const rtl::OUString & str, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw ( ::com::sun::star::container::ElementExistException ); + + +public: // XDrop + virtual void SAL_CALL dropByName( const ::rtl::OUString& elementName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException) = 0; + +public: // XRefreshable + virtual void SAL_CALL refresh( ) throw (::com::sun::star::uno::RuntimeException) {} + virtual void SAL_CALL addRefreshListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener >& l ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeRefreshListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener >& l ) + throw (::com::sun::star::uno::RuntimeException); + +public: + // Methods + virtual void SAL_CALL addContainerListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeContainerListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) + throw (::com::sun::star::uno::RuntimeException); + +public: + virtual void SAL_CALL disposing(); + +public: + void rename( const rtl::OUString & oldName, const rtl::OUString &newName ); + +protected: + void fire( const EventBroadcastHelper & helper ); +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_xindex.cxx connectivity/source/drivers/postgresql/pq_xindex.cxx new file mode 100644 index 0000000..6edcb7e --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xindex.cxx @@ -0,0 +1,267 @@ +/************************************************************************* + * + * $RCSfile: pq_xindex.cxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:01 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "pq_xindex.hxx" +#include "pq_xindexcolumns.hxx" +#include "pq_tools.hxx" +#include "pq_statics.hxx" + +using osl::MutexGuard; +using osl::Mutex; + +using rtl::OUString; +using rtl::OUStringBuffer; + +using com::sun::star::container::XNameAccess; +using com::sun::star::container::XIndexAccess; +using com::sun::star::container::ElementExistException; +using com::sun::star::container::NoSuchElementException; + +using com::sun::star::uno::Reference; +using com::sun::star::uno::Exception; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::lang::IllegalArgumentException; +using com::sun::star::lang::IndexOutOfBoundsException; + +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::XFastPropertySet; +using com::sun::star::beans::XMultiPropertySet; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::Property; + +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::SQLException; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +Index::Index( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings, + const rtl::OUString & schemaName, + const rtl::OUString & tableName ) + : ReflectionBase( + getStatics().refl.index.implName, + getStatics().refl.index.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.index.pProps ), + m_schemaName( schemaName ), + m_tableName( tableName ) +{} + +Reference< XPropertySet > Index::createDataDescriptor( ) throw (RuntimeException) +{ + IndexDescriptor * pIndex = new IndexDescriptor( + m_refMutex, m_conn, m_pSettings ); + pIndex->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pIndex ); +} + +Reference< XNameAccess > Index::getColumns( ) throw (::com::sun::star::uno::RuntimeException) +{ + if( ! m_indexColumns.is() ) + { + Sequence< OUString > columnNames; + getPropertyValue( getStatics().PRIVATE_COLUMN_INDEXES ) >>= columnNames; + OUString indexName = extractStringProperty( this, getStatics().NAME ); + m_indexColumns = IndexColumns::create( + m_refMutex, m_conn, m_pSettings, m_schemaName, + m_tableName, indexName, columnNames ); + } + return m_indexColumns; +} + +Sequence Index::getTypes() throw( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< com::sun::star::sdbcx::XColumnsSupplier> *) 0 ), + ReflectionBase::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> Index::getImplementationId() throw( RuntimeException ) +{ + return getStatics().refl.index.implementationId; +} + +Any Index::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = ReflectionBase::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this ) ); + return ret; +} + + +//___________________________________________________________________________________ +IndexDescriptor::IndexDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings ) + : ReflectionBase( + getStatics().refl.indexDescriptor.implName, + getStatics().refl.indexDescriptor.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.indexDescriptor.pProps ) +{} + +Reference< XPropertySet > IndexDescriptor::createDataDescriptor( ) throw (RuntimeException) +{ + IndexDescriptor * pIndex = new IndexDescriptor( + m_refMutex, m_conn, m_pSettings ); + pIndex->copyValuesFrom( this ); + return Reference< XPropertySet > ( pIndex ); +} + +Reference< XNameAccess > IndexDescriptor::getColumns( ) throw (::com::sun::star::uno::RuntimeException) +{ + if( ! m_indexColumns.is() ) + { + m_indexColumns = IndexColumnDescriptors::create( + m_refMutex, m_conn, m_pSettings ); +// Sequence< OUString > columnNames; +// getPropertyValue( getStatics().PRIVATE_COLUMN_INDEXES ) >>= columnNames; +// OUString indexName = extractStringProperty( this, getStatics().NAME ); +// m_indexColumns = IndexColumns::create( +// m_refMutex, m_conn, m_pSettings, m_schemaName, +// m_tableName, indexName, columnNames ); + } + return m_indexColumns; +} + +Sequence IndexDescriptor::getTypes() throw( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< com::sun::star::sdbcx::XColumnsSupplier> *) 0 ), + ReflectionBase::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> IndexDescriptor::getImplementationId() throw( RuntimeException ) +{ + return getStatics().refl.indexDescriptor.implementationId; +} + +Any IndexDescriptor::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = ReflectionBase::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this ) ); + return ret; +} + + + + +} diff --git connectivity/source/drivers/postgresql/pq_xindex.hxx connectivity/source/drivers/postgresql/pq_xindex.hxx new file mode 100644 index 0000000..43451f4 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xindex.hxx @@ -0,0 +1,156 @@ +/************************************************************************* + * + * $RCSfile: pq_xindex.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:02 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_XINDEX_HXX +#define HEADER_PQ_XINDEX_HXX + +#include +#include + +#include +#include +#include + +#include "pq_connection.hxx" +#include "pq_xbase.hxx" + +namespace pq_sdbc_driver +{ + +class Index : public ReflectionBase, + public com::sun::star::sdbcx::XColumnsSupplier +{ + ::com::sun::star::uno::Reference< com::sun::star::sdbc::XDatabaseMetaData > m_meta; + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_indexColumns; + + rtl::OUString m_schemaName; + rtl::OUString m_tableName; + +public: + Index( const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XColumnsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL + getColumns( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +}; + + +class IndexDescriptor : public ReflectionBase, + public com::sun::star::sdbcx::XColumnsSupplier +{ + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_indexColumns; + +public: + IndexDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XColumnsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL + getColumns( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +}; + + +} + + +#endif diff --git connectivity/source/drivers/postgresql/pq_xindexcolumn.cxx connectivity/source/drivers/postgresql/pq_xindexcolumn.cxx new file mode 100644 index 0000000..4e974af --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xindexcolumn.cxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * $RCSfile: pq_xindexcolumn.cxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:03 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include "pq_xindexcolumn.hxx" + +using com::sun::star::uno::Any; +using com::sun::star::uno::Reference; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Type; +using com::sun::star::uno::Sequence; + +using com::sun::star::beans::XPropertySet; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +IndexColumn::IndexColumn( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings ) + : ReflectionBase( + getStatics().refl.indexColumn.implName, + getStatics().refl.indexColumn.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.indexColumn.pProps ) +{} + +Reference< XPropertySet > IndexColumn::createDataDescriptor( ) throw (RuntimeException) +{ + IndexColumnDescriptor * pIndexColumn = new IndexColumnDescriptor( + m_refMutex, m_conn, m_pSettings ); + pIndexColumn->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pIndexColumn ); +} + + +IndexColumnDescriptor::IndexColumnDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings ) + : ReflectionBase( + getStatics().refl.indexColumnDescriptor.implName, + getStatics().refl.indexColumnDescriptor.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.indexColumnDescriptor.pProps ) +{} + +Reference< XPropertySet > IndexColumnDescriptor::createDataDescriptor( ) throw (RuntimeException) +{ + IndexColumnDescriptor * pIndexColumn = new IndexColumnDescriptor( + m_refMutex, m_conn, m_pSettings ); + pIndexColumn->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pIndexColumn ); +} + +} diff --git connectivity/source/drivers/postgresql/pq_xindexcolumn.hxx connectivity/source/drivers/postgresql/pq_xindexcolumn.hxx new file mode 100644 index 0000000..ff6dd52 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xindexcolumn.hxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * $RCSfile: pq_xindexcolumn.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:04 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_INDEXCOLUMN_HXX +#define HEADER_PQ_INDEXCOLUMN_HXX + +#include +#include + +#include +#include + +#include "pq_connection.hxx" +#include "pq_xbase.hxx" + +namespace pq_sdbc_driver +{ + +class IndexColumn : public ReflectionBase +{ +public: + IndexColumn( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +}; + +class IndexColumnDescriptor : public ReflectionBase +{ +public: + IndexColumnDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +}; + + +} + + +#endif diff --git connectivity/source/drivers/postgresql/pq_xindexcolumns.cxx connectivity/source/drivers/postgresql/pq_xindexcolumns.cxx new file mode 100644 index 0000000..4218cf5 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xindexcolumns.cxx @@ -0,0 +1,322 @@ +/************************************************************************* + * + * $RCSfile: pq_xindexcolumns.cxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/08/29 08:33:31 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "pq_xcolumns.hxx" +#include "pq_xindexcolumns.hxx" +#include "pq_xindexcolumn.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::beans::XPropertySet; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::container::NoSuchElementException; +using com::sun::star::lang::WrappedTargetException; + +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XDatabaseMetaData; +using com::sun::star::sdbc::SQLException; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +IndexColumns::IndexColumns( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + const rtl::OUString &indexName, + const com::sun::star::uno::Sequence< rtl::OUString > &columns ) + : Container( refMutex, origin, pSettings, ASCII_STR( "INDEX_COLUMN" ) ), + m_schemaName( schemaName ), + m_tableName( tableName ), + m_columns( columns ), + m_indexName( indexName ) +{} + +IndexColumns::~IndexColumns() +{} + +static sal_Int32 findInSequence( const Sequence< rtl::OUString > & seq , const rtl::OUString &str) +{ + int index; + for( index = 0 ; index < seq.getLength() ; index ++ ) + { + if( str == seq[index] ) + break; + } + return index; +} + +void IndexColumns::refresh() + throw (::com::sun::star::uno::RuntimeException) +{ + try + { + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + rtl::OStringBuffer buf; + buf.append( "sdbcx.IndexColumns get refreshed for index " ); + buf.append( OUStringToOString( m_indexName, m_pSettings->encoding ) ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() ); + } + + osl::MutexGuard guard( m_refMutex->mutex ); + + 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 ); + m_values = Sequence< Any >( m_columns.getLength() ); + + while( rs->next() ) + { + OUString columnName = xRow->getString( 4 ); + + sal_Int32 index = findInSequence( m_columns, columnName ); + if( index >= m_columns.getLength() ) + continue; + + IndexColumn * pIndexColumn = + new IndexColumn( m_refMutex, m_origin, m_pSettings ); + Reference< com::sun::star::beans::XPropertySet > prop = pIndexColumn; + + columnMetaData2SDBCX( pIndexColumn, xRow ); + pIndexColumn->setPropertyValue_NoBroadcast_public( + st.IS_ASCENDING , makeAny( (sal_Bool ) sal_False ) ); + + m_values[ index ] = makeAny( prop ); + m_name2index[ columnName ] = index; + } + } + catch ( com::sun::star::sdbc::SQLException & e ) + { + throw RuntimeException( e.Message , e.Context ); + } + + fire( RefreshedBroadcaster( *this ) ); +} + + +void IndexColumns::appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& future ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + OUString name = extractStringProperty( future, getStatics().NAME ); + throw com::sun::star::sdbc::SQLException( + ASCII_STR( "SDBC-POSTGRESQL: IndexesColumns.appendByDescriptor not yet implemented" ), + *this, OUString(), 1, Any() ); +// osl::MutexGuard guard( m_refMutex->mutex ); +// Statics & st = getStatics(); +// Reference< XPropertySet > past = createDataDescriptor(); +// past->setPropertyValue( st.IS_NULLABLE, makeAny( com::sun::star::sdbc::ColumnValue::NULLABLE ) ); +// alterColumnByDescriptor( +// m_schemaName, m_tableName, m_pSettings->encoding, m_origin->createStatement() , past, future ); + +} + +void IndexColumns::dropByName( const ::rtl::OUString& elementName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException) +{ + throw com::sun::star::sdbc::SQLException( + ASCII_STR( "SDBC-POSTGRESQL: IndexesColumns.dropByName not yet implemented" ), + *this, OUString(), 1, Any() ); +// 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 com::sun::star::container::NoSuchElementException( +// buf.makeStringAndClear(), *this ); +// } +// dropByIndex( ii->second ); +} + +void IndexColumns::dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException) +{ + throw com::sun::star::sdbc::SQLException( + ASCII_STR( "SDBC-POSTGRESQL: IndexesColumns.dropByIndex not yet implemented" ), + *this, OUString(), 1, Any() ); +// osl::MutexGuard guard( m_refMutex->mutex ); +// if( index < 0 || index >= m_values.getLength() ) +// { +// OUStringBuffer buf( 128 ); +// buf.appendAscii( "COLUMNS: Index out of range (allowed 0 to " ); +// buf.append((sal_Int32)(m_values.getLength() -1) ); +// buf.appendAscii( ", got " ); +// buf.append( index ); +// buf.appendAscii( ")" ); +// throw com::sun::star::lang::IndexOutOfBoundsException( +// buf.makeStringAndClear(), *this ); +// } + +// Reference< XPropertySet > set; +// m_values[index] >>= set; +// Statics &st = getStatics(); +// OUString name; +// set->getPropertyValue( st.NAME ) >>= name; + +// OUStringBuffer update( 128 ); +// update.appendAscii( "ALTER TABLE ONLY"); +// bufferQuoteQualifiedIdentifier( update, m_schemaName, m_tableName ); +// update.appendAscii( "DROP COLUMN" ); +// bufferQuoteIdentifier( update, name ); +// Reference< XStatement > stmt = m_origin->createStatement( ); +// DisposeGuard disposeIt( stmt ); +// stmt->executeUpdate( update.makeStringAndClear() ); + +} + + +Reference< ::com::sun::star::beans::XPropertySet > IndexColumns::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new IndexColumnDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +Reference< com::sun::star::container::XNameAccess > IndexColumns::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + const rtl::OUString &indexName, + const Sequence< rtl::OUString > &columns ) +{ + IndexColumns *pIndexColumns = new IndexColumns( + refMutex, origin, pSettings, schemaName, tableName, indexName, columns ); + Reference< com::sun::star::container::XNameAccess > ret = pIndexColumns; + pIndexColumns->refresh(); + + return ret; +} + +//_________________________________________________________________________________________ +IndexColumnDescriptors::IndexColumnDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings) + : Container( refMutex, origin, pSettings, getStatics().INDEX_COLUMN ) +{} + +Reference< com::sun::star::container::XNameAccess > IndexColumnDescriptors::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings) +{ + return new IndexColumnDescriptors( refMutex, origin, pSettings ); +} + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > IndexColumnDescriptors::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new IndexColumnDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +}; diff --git connectivity/source/drivers/postgresql/pq_xindexcolumns.hxx connectivity/source/drivers/postgresql/pq_xindexcolumns.hxx new file mode 100644 index 0000000..b4bec81 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xindexcolumns.hxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * $RCSfile: pq_xindexcolumns.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:05 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_INDEXCOLUMNS_HXX +#define HEADER_PQ_INDEXCOLUMNS_HXX + +#include "pq_xcontainer.hxx" + +namespace pq_sdbc_driver +{ + +class IndexColumns : public Container +{ + rtl::OUString m_schemaName; + rtl::OUString m_tableName; + rtl::OUString m_indexName; + com::sun::star::uno::Sequence< rtl::OUString > m_columns; + +public: // instances IndexColumns 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + const rtl::OUString &indexName, + const com::sun::star::uno::Sequence< ::rtl::OUString > &columns ); + +protected: + IndexColumns( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + const rtl::OUString &indexName, + const com::sun::star::uno::Sequence< ::rtl::OUString > &columns ); + + virtual ~IndexColumns(); + +public: // XAppend + virtual void SAL_CALL appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +public: // XDrop + virtual void SAL_CALL dropByName( const ::rtl::OUString& elementName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // XRefreshable + virtual void SAL_CALL refresh( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); +}; + + +class IndexColumnDescriptors : public Container +{ + +public: // instances IndexColumns 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ); + +protected: + IndexColumnDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_xindexes.cxx connectivity/source/drivers/postgresql/pq_xindexes.cxx new file mode 100644 index 0000000..d54d304 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xindexes.cxx @@ -0,0 +1,355 @@ +/************************************************************************* + * + * $RCSfile: pq_xindexes.cxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/08/29 08:33:31 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "pq_xindexes.hxx" +#include "pq_xindex.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::beans::XPropertySet; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::container::NoSuchElementException; +using com::sun::star::container::XEnumerationAccess; +using com::sun::star::container::XEnumeration; + +using com::sun::star::lang::WrappedTargetException; + +using com::sun::star::sdbcx::XColumnsSupplier; + +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XDatabaseMetaData; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +Indexes::Indexes( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName) + : Container( refMutex, origin, pSettings, getStatics().KEY ), + m_schemaName( schemaName ), + m_tableName( tableName ) +{ +} + +Indexes::~Indexes() +{} + +void Indexes::refresh() + throw (::com::sun::star::uno::RuntimeException) +{ + try + { + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + rtl::OStringBuffer buf; + buf.append( "sdbcx.Indexes get refreshed for table " ); + buf.append( OUStringToOString( m_schemaName, m_pSettings->encoding ) ); + buf.append( "." ); + buf.append( OUStringToOString( m_tableName,m_pSettings->encoding ) ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() ); + } + + osl::MutexGuard guard( m_refMutex->mutex ); + Statics & st = getStatics(); + + Int2StringMap column2NameMap; + fillAttnum2attnameMap( column2NameMap, m_origin, m_schemaName, m_tableName ); + + // see XDatabaseMetaData::getIndexInfo() + Reference< XPreparedStatement > stmt = m_origin->prepareStatement( + ASCII_STR( + "SELECT nspname, " // 1 + "pg_class.relname, " // 2 + "class2.relname, " // 3 + "indisclustered, " // 4 + "indisunique, " // 5 + "indisprimary, " // 6 + "indkey " // 7 + "FROM pg_index INNER JOIN pg_class ON indrelid = pg_class.oid " + "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid " + "INNER JOIN pg_class as class2 ON pg_index.indexrelid = class2.oid " + "WHERE nspname = ? AND pg_class.relname = ?" ) ); + + Reference< XParameters > params( stmt, UNO_QUERY); + params->setString( 1, m_schemaName ); + params->setString( 2, m_tableName ); + Reference< XResultSet > rs = stmt->executeQuery(); + + Reference< XRow > row( rs, UNO_QUERY ); + String2IntMap map; + std::vector< Any, Allocator< Any> > vec; + sal_Int32 index = 0; + while( rs->next() ) + { + static const sal_Int32 C_SCHEMA = 1; + static const sal_Int32 C_TABLENAME = 2; + static const sal_Int32 C_INDEXNAME = 3; + static const sal_Int32 C_IS_CLUSTERED = 4; + static const sal_Int32 C_IS_UNIQUE = 5; + static const sal_Int32 C_IS_PRIMARY = 6; + static const sal_Int32 C_COLUMNS = 7; + OUString currentIndexName = row->getString( C_INDEXNAME ); + Index *pIndex = + new Index( m_refMutex, m_origin, m_pSettings, + m_schemaName, m_tableName ); + + sal_Bool isUnique = row->getBoolean( C_IS_UNIQUE ); + sal_Bool isPrimary = row->getBoolean( C_IS_PRIMARY ); + sal_Bool isClusterd = row->getBoolean( C_IS_CLUSTERED ); + Reference< com::sun::star::beans::XPropertySet > prop = pIndex; + pIndex->setPropertyValue_NoBroadcast_public( + st.IS_UNIQUE, Any( &isUnique, getBooleanCppuType() ) ); + pIndex->setPropertyValue_NoBroadcast_public( + st.IS_PRIMARY_KEY_INDEX, Any( &isPrimary, getBooleanCppuType() ) ); + pIndex->setPropertyValue_NoBroadcast_public( + st.IS_CLUSTERED, Any( &isClusterd, getBooleanCppuType() ) ); + pIndex->setPropertyValue_NoBroadcast_public( + st.NAME, makeAny( currentIndexName ) ); + + Sequence< sal_Int32 > seq = parseIntArray( row->getString( C_COLUMNS ) ); + Sequence< OUString > columnNames(seq.getLength()); + for( int columns = 0 ; columns < seq.getLength() ; columns ++ ) + { + columnNames[columns] = column2NameMap[ seq[columns] ]; + } + + pIndex->setPropertyValue_NoBroadcast_public( + st.PRIVATE_COLUMN_INDEXES, makeAny( columnNames )); + + vec.push_back( makeAny( prop ) ); + map[ currentIndexName ] = index; + index ++; + } + m_values = Sequence< com::sun::star::uno::Any > ( & vec[0] , vec.size() ); + m_name2index.swap( map ); + } + catch ( com::sun::star::sdbc::SQLException & e ) + { + throw RuntimeException( e.Message , e.Context ); + } + + fire( RefreshedBroadcaster( *this ) ); +} + + +void Indexes::appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + Statics & st = getStatics(); + OUString name = extractStringProperty( descriptor, st.NAME ); + + sal_Bool isUnique = extractBoolProperty( descriptor, st.IS_UNIQUE ); + + OUStringBuffer buf( 128 ); + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "CREATE " ) ); + if( isUnique ) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "UNIQUE " ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "INDEX " ) ); + bufferQuoteIdentifier( buf, name ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ON " ) ); + bufferQuoteQualifiedIdentifier( buf, m_schemaName, m_tableName ); + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ( " ) ); + + Reference< XColumnsSupplier > columns( descriptor, UNO_QUERY ); + if( columns.is() ) + { + Reference< XEnumerationAccess > access( columns->getColumns(), UNO_QUERY ); + if( access.is() ) + { + Reference< XEnumeration > xEnum( access->createEnumeration() ); + bool first = true; + while( xEnum.is() && xEnum->hasMoreElements() ) + { + Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY ); + if( first ) + { + first = false; + } + else + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) ); + } + buf.append( extractStringProperty( column, st.NAME ) ); + } + } + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ) " ) ); + + m_origin->createStatement()->executeUpdate( buf.makeStringAndClear() ); + refresh(); +} + +void Indexes::dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException) +{ + + + osl::MutexGuard guard( m_refMutex->mutex ); + if( index < 0 || index >= m_values.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "Indexes: Index out of range (allowed 0 to " ); + buf.append( (sal_Int32) (m_values.getLength() -1) ); + buf.appendAscii( ", got " ); + buf.append( index ); + buf.appendAscii( ")" ); + throw com::sun::star::lang::IndexOutOfBoundsException( + buf.makeStringAndClear(), *this ); + } + + Reference< XPropertySet > set; + m_values[index] >>= set; + Statics &st = getStatics(); + + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "DROP INDEX " ) ); + bufferQuoteIdentifier( buf, extractStringProperty( set, st.NAME ) ); + m_origin->createStatement()->executeUpdate( buf.makeStringAndClear() ); + + Container::dropByIndex( index ); +} + + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Indexes::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new IndexDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +Reference< com::sun::star::container::XNameAccess > Indexes::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString & schemaName, + const rtl::OUString & tableName) +{ + Indexes *pIndexes = new Indexes( refMutex, origin, pSettings, schemaName, tableName ); + Reference< com::sun::star::container::XNameAccess > ret = pIndexes; + pIndexes->refresh(); + return ret; +} + + +//_________________________________________________________________________________________ +IndexDescriptors::IndexDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings) + : Container( refMutex, origin, pSettings, getStatics().INDEX ) +{} + +Reference< com::sun::star::container::XNameAccess > IndexDescriptors::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings) +{ + return new IndexDescriptors( refMutex, origin, pSettings ); +} + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > IndexDescriptors::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new IndexDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +}; diff --git connectivity/source/drivers/postgresql/pq_xindexes.hxx connectivity/source/drivers/postgresql/pq_xindexes.hxx new file mode 100644 index 0000000..bdb32a0 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xindexes.hxx @@ -0,0 +1,135 @@ +/************************************************************************* + * + * $RCSfile: pq_xindexes.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:07 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_INDEXES_HXX_ +#define HEADER_PQ_INDEXES_HXX_ + +#include "pq_xcontainer.hxx" + +namespace pq_sdbc_driver +{ +class Indexes : public Container +{ + rtl::OUString m_schemaName; + rtl::OUString m_tableName; + +public: // instances Columns 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName); + +protected: + Indexes( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName); + + virtual ~Indexes(); + +public: // XAppend + virtual void SAL_CALL appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +public: // XDrop + virtual void SAL_CALL dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // XRefreshable + virtual void SAL_CALL refresh( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); +}; + + +class IndexDescriptors : public Container +{ +public: // instances IndexDescriptors 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ); + +protected: + IndexDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); + +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_xkey.cxx connectivity/source/drivers/postgresql/pq_xkey.cxx new file mode 100644 index 0000000..87f5394 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xkey.cxx @@ -0,0 +1,262 @@ +/************************************************************************* + * + * $RCSfile: pq_xkey.cxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:07 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "pq_xkey.hxx" +#include "pq_xkeycolumns.hxx" +#include "pq_tools.hxx" +#include "pq_statics.hxx" + +using osl::MutexGuard; +using osl::Mutex; + +using rtl::OUString; +using rtl::OUStringBuffer; + +using com::sun::star::container::XNameAccess; +using com::sun::star::container::XIndexAccess; +using com::sun::star::container::ElementExistException; +using com::sun::star::container::NoSuchElementException; + +using com::sun::star::uno::Reference; +using com::sun::star::uno::Exception; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::lang::IllegalArgumentException; +using com::sun::star::lang::IndexOutOfBoundsException; + +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::XFastPropertySet; +using com::sun::star::beans::XMultiPropertySet; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::Property; + +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::SQLException; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +Key::Key( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings, + const rtl::OUString & schemaName, + const rtl::OUString & tableName ) + : ReflectionBase( + getStatics().refl.key.implName, + getStatics().refl.key.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.key.pProps ), + m_schemaName( schemaName ), + m_tableName( tableName ) +{} + +Reference< XPropertySet > Key::createDataDescriptor( ) throw (RuntimeException) +{ + KeyDescriptor * pKeyDescriptor = new KeyDescriptor( + m_refMutex, m_conn, m_pSettings ); + pKeyDescriptor->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pKeyDescriptor ); +} + +Reference< XNameAccess > Key::getColumns( ) throw (::com::sun::star::uno::RuntimeException) +{ + // TODO: cash columns object ! + if( !m_keyColumns.is() ) + { + Sequence< OUString > columnNames, foreignColumnNames; + getPropertyValue( getStatics().PRIVATE_COLUMNS ) >>= columnNames; + getPropertyValue( getStatics().PRIVATE_FOREIGN_COLUMNS ) >>= foreignColumnNames; + + m_keyColumns = KeyColumns::create( + m_refMutex, m_conn, m_pSettings, m_schemaName, + m_tableName, columnNames, foreignColumnNames ); + } + return m_keyColumns; +} + +Sequence Key::getTypes() throw( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< com::sun::star::sdbcx::XColumnsSupplier> *) 0 ), + ReflectionBase::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> Key::getImplementationId() throw( RuntimeException ) +{ + return getStatics().refl.key.implementationId; +} + +Any Key::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = ReflectionBase::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this ) ); + return ret; +} + + +//_____________________________________________________________________________ +KeyDescriptor::KeyDescriptor( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings ) + : ReflectionBase( + getStatics().refl.keyDescriptor.implName, + getStatics().refl.keyDescriptor.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.keyDescriptor.pProps ) +{ +} + +Reference< XPropertySet > KeyDescriptor::createDataDescriptor( ) throw (RuntimeException) +{ + KeyDescriptor * pKeyDescriptor = new KeyDescriptor( + m_refMutex, m_conn, m_pSettings ); + pKeyDescriptor->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pKeyDescriptor ); +} + +Reference< XNameAccess > KeyDescriptor::getColumns( ) throw (::com::sun::star::uno::RuntimeException) +{ + // TODO: cash columns object ! + if( !m_keyColumns.is() ) + { + m_keyColumns = new KeyColumnDescriptors( m_refMutex, m_conn, m_pSettings ); + } + return m_keyColumns; +} + +Sequence KeyDescriptor::getTypes() throw( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< com::sun::star::sdbcx::XColumnsSupplier> *) 0 ), + ReflectionBase::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> KeyDescriptor::getImplementationId() throw( RuntimeException ) +{ + return getStatics().refl.keyDescriptor.implementationId; +} + +Any KeyDescriptor::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = ReflectionBase::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this ) ); + return ret; +} + + +} diff --git connectivity/source/drivers/postgresql/pq_xkey.hxx connectivity/source/drivers/postgresql/pq_xkey.hxx new file mode 100644 index 0000000..4e3409b --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xkey.hxx @@ -0,0 +1,152 @@ +/************************************************************************* + * + * $RCSfile: pq_xkey.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_KEY_HXX_ +#define HEADER_PQ_KEY_HXX_ + +#include +#include + +#include +#include +#include + +#include "pq_connection.hxx" +#include "pq_xbase.hxx" + +namespace pq_sdbc_driver +{ + +class Key : public ReflectionBase, + public com::sun::star::sdbcx::XColumnsSupplier +{ + ::com::sun::star::uno::Reference< com::sun::star::sdbc::XDatabaseMetaData > m_meta; + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_keyColumns; + + rtl::OUString m_schemaName; + rtl::OUString m_tableName; + +public: + Key( const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XColumnsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL + getColumns( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +}; + + +class KeyDescriptor : public ReflectionBase, public com::sun::star::sdbcx::XColumnsSupplier +{ + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_keyColumns; + +public: + KeyDescriptor( const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings ); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XColumnsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL + getColumns( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); +}; + +} + + +#endif diff --git connectivity/source/drivers/postgresql/pq_xkeycolumn.cxx connectivity/source/drivers/postgresql/pq_xkeycolumn.cxx new file mode 100644 index 0000000..2d5fe72 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xkeycolumn.cxx @@ -0,0 +1,121 @@ +/************************************************************************* + * + * $RCSfile: pq_xkeycolumn.cxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include "pq_xkeycolumn.hxx" + +using com::sun::star::uno::Any; +using com::sun::star::uno::Reference; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Type; +using com::sun::star::uno::Sequence; + +using com::sun::star::beans::XPropertySet; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +KeyColumn::KeyColumn( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings) + : ReflectionBase( + getStatics().refl.keycolumn.implName, + getStatics().refl.keycolumn.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.keycolumn.pProps ) +{} + +Reference< XPropertySet > KeyColumn::createDataDescriptor( ) throw (RuntimeException) +{ + KeyColumnDescriptor * pKeyColumn = new KeyColumnDescriptor( + m_refMutex, m_conn, m_pSettings ); + pKeyColumn->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pKeyColumn ); +} + +KeyColumnDescriptor::KeyColumnDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings) + : ReflectionBase( + getStatics().refl.keycolumnDescriptor.implName, + getStatics().refl.keycolumnDescriptor.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.keycolumnDescriptor.pProps ) +{} + +Reference< XPropertySet > KeyColumnDescriptor::createDataDescriptor( ) throw (RuntimeException) +{ + KeyColumnDescriptor * pKeyColumn = new KeyColumnDescriptor( + m_refMutex, m_conn, m_pSettings ); + pKeyColumn->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pKeyColumn ); +} + +} diff --git connectivity/source/drivers/postgresql/pq_xkeycolumn.hxx connectivity/source/drivers/postgresql/pq_xkeycolumn.hxx new file mode 100644 index 0000000..7aaacff --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xkeycolumn.hxx @@ -0,0 +1,108 @@ +/************************************************************************* + * + * $RCSfile: pq_xkeycolumn.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:09 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_KEYCOLUMN_HXX +#define HEADER_PQ_KEYCOLUMN_HXX + +#include +#include + +#include +#include + +#include "pq_connection.hxx" +#include "pq_xbase.hxx" + +namespace pq_sdbc_driver +{ + +class KeyColumn : public ReflectionBase +{ +public: + KeyColumn( const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +}; + +class KeyColumnDescriptor : public ReflectionBase +{ +public: + KeyColumnDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +}; + + +} + + +#endif diff --git connectivity/source/drivers/postgresql/pq_xkeycolumns.cxx connectivity/source/drivers/postgresql/pq_xkeycolumns.cxx new file mode 100644 index 0000000..898b81c --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xkeycolumns.cxx @@ -0,0 +1,411 @@ +/************************************************************************* + * + * $RCSfile: pq_xkeycolumns.cxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2004/08/29 08:33:31 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "pq_xcolumns.hxx" +#include "pq_xkeycolumns.hxx" +#include "pq_xkeycolumn.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::beans::XPropertySet; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::container::NoSuchElementException; +using com::sun::star::lang::WrappedTargetException; + +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XDatabaseMetaData; +using com::sun::star::sdbc::SQLException; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +KeyColumns::KeyColumns( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + const Sequence< rtl::OUString > &columnNames, + const Sequence< rtl::OUString > &foreignColumnNames ) + : Container( refMutex, origin, pSettings, ASCII_STR( "KEY_COLUMN" ) ), + m_schemaName( schemaName ), + m_tableName( tableName ), + m_columnNames( columnNames ), + m_foreignColumnNames( foreignColumnNames ) +{} + +KeyColumns::~KeyColumns() +{} + + +void KeyColumns::refresh() + throw (::com::sun::star::uno::RuntimeException) +{ + try + { + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + rtl::OStringBuffer buf; + buf.append( "sdbcx.KeyColumns get refreshed for table " ); + buf.append( OUStringToOString( m_schemaName, m_pSettings->encoding ) ); + buf.append( "." ); + buf.append( OUStringToOString( m_tableName, m_pSettings->encoding ) ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() ); + } + + osl::MutexGuard guard( m_refMutex->mutex ); + + 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; + + std::vector< Any, Allocator< Any> > vec; + sal_Int32 columnIndex = 0; + while( rs->next() ) + { + OUString columnName = xRow->getString( 4 ); + + int keyindex; + for( keyindex = 0 ; keyindex < m_columnNames.getLength() ; keyindex ++ ) + { + if( columnName == m_columnNames[keyindex] ) + break; + } + if( m_columnNames.getLength() == keyindex ) + continue; + + KeyColumn * pKeyColumn = + new KeyColumn( m_refMutex, m_origin, m_pSettings ); + Reference< com::sun::star::beans::XPropertySet > prop = pKeyColumn; + + OUString name = columnMetaData2SDBCX( pKeyColumn, xRow ); + if( keyindex < m_foreignColumnNames.getLength() ) + { + pKeyColumn->setPropertyValue_NoBroadcast_public( + st.RELATED_COLUMN, makeAny( m_foreignColumnNames[keyindex]) ); + } + + vec.push_back( makeAny( prop ) ); + map[ name ] = columnIndex; + columnIndex ++; + } + m_values = Sequence< com::sun::star::uno::Any > ( & vec[0] , vec.size() ); + m_name2index.swap( map ); + } + catch ( com::sun::star::sdbc::SQLException & e ) + { + throw RuntimeException( e.Message , e.Context ); + } + + fire( RefreshedBroadcaster( *this ) ); +} + + +// void alterColumnByDescriptor( +// const OUString & schemaName, +// const OUString & tableName, +// rtl_TextEncoding encoding, +// const Reference< XStatement > &stmt, +// const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > & past, +// const com::sun::star::uno::Reference< com::sun::star::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.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Can't move column " ) ); +// // buf.append( extractStringProperty( past, st.COLUMN_NAME ) ); +// // buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " from table " ) ); +// // buf.append( extractStringProperty( past, st.TABLE_NAME ) ); +// // buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " to table " ) ); +// // buf.append( extractStringProperty( past, st.TABLE_NAME ) ); +// // throw SQLException( buf.makeStringAndClear(), Reference< XInterface > () ); +// // } + +// // 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.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); +// bufferQuoteQualifiedIdentifier( buf, schemaName, tableName ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ADD COLUMN" ) ); +// bufferQuoteIdentifier( buf, futureColumnName ); +// buf.append( futureTypeName ); +// transaction.executeUpdate( buf.makeStringAndClear() ); +// } +// else +// { +// if( pastTypeName != futureTypeName ) +// { +// throw RuntimeException( +// ASCII_STR( "Can't modify column types, drop the column and create a new one" ), +// Reference< XInterface > () ); +// } + +// if( pastColumnName != futureColumnName ) +// { +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); +// bufferQuoteQualifiedIdentifier( buf, schemaName, tableName ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "RENAME COLUMN" ) ); +// bufferQuoteIdentifier( buf, pastColumnName ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "TO" ) ); +// bufferQuoteIdentifier( buf, futureColumnName ); +// transaction.executeUpdate( buf.makeStringAndClear() ); +// } +// } + +// OUString futureDefaultValue = extractStringProperty( future, st.DEFAULT_VALUE ); +// OUString pastDefaultValue = extractStringProperty( past, st.DEFAULT_VALUE ); +// if( futureDefaultValue != pastDefaultValue ) +// { +// buf = OUStringBuffer( 128 ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); +// bufferQuoteQualifiedIdentifier( buf, schemaName, tableName ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER COLUMN" ) ); +// bufferQuoteIdentifier( buf, futureColumnName ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SET DEFAULT " ) ); +// // default value is not quoted, caller needs to quote himself (otherwise +// // how to pass e.g. nextval('something' ) ???? +// buf.append( 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 = OUStringBuffer( 128 ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); +// bufferQuoteQualifiedIdentifier( buf, schemaName, tableName ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER COLUMN" ) ); +// bufferQuoteIdentifier( buf, futureColumnName ); +// if( futureNullable == com::sun::star::sdbc::ColumnValue::NO_NULLS ) +// { +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SET" ) ); +// } +// else +// { +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "DROP" ) ); +// } +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " NOT NULL" ) ); +// transaction.executeUpdate( buf.makeStringAndClear() ); +// } + +// OUString futureComment = extractStringProperty( future, st.DESCRIPTION ); +// OUString pastComment = extractStringProperty( past, st.DESCRIPTION ); +// if( futureComment != pastComment ) +// { +// buf = OUStringBuffer( 128 ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "COMMENT ON COLUMN" ) ); +// bufferQuoteQualifiedIdentifier( buf, schemaName, tableName , futureColumnName ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "IS " ) ); +// bufferQuoteConstant( buf, futureComment,encoding); +// transaction.executeUpdate( buf.makeStringAndClear() ); +// } +// transaction.commit(); +// } + +void KeyColumns::appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& future ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + throw com::sun::star::sdbc::SQLException( + ASCII_STR( "KeyColumns::appendByDescriptor not implemented yet" ), + *this, OUString(), 1, Any() ); + +// osl::MutexGuard guard( m_refMutex->mutex ); +// Statics & st = getStatics(); +// Reference< XPropertySet > past = createDataDescriptor(); +// past->setPropertyValue( st.IS_NULLABLE, makeAny( com::sun::star::sdbc::ColumnValue::NULLABLE ) ); +// alterColumnByDescriptor( +// m_schemaName, m_tableName, m_pSettings->encoding, m_origin->createStatement() , past, future ); + +} + + +void KeyColumns::dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException) +{ + throw com::sun::star::sdbc::SQLException( + ASCII_STR( "KeyColumns::dropByIndex not implemented yet" ), + *this, OUString(), 1, Any() ); +// osl::MutexGuard guard( m_refMutex->mutex ); +// if( index < 0 || index >= m_values.getLength() ) +// { +// OUStringBuffer buf( 128 ); +// buf.appendAscii( "COLUMNS: Index out of range (allowed 0 to " ); +// buf.append((sal_Int32)(m_values.getLength() -1) ); +// buf.appendAscii( ", got " ); +// buf.append( index ); +// buf.appendAscii( ")" ); +// throw com::sun::star::lang::IndexOutOfBoundsException( +// buf.makeStringAndClear(), *this ); +// } + +// Reference< XPropertySet > set; +// m_values[index] >>= set; +// Statics &st = getStatics(); +// OUString name; +// set->getPropertyValue( st.NAME ) >>= name; + +// OUStringBuffer update( 128 ); +// update.appendAscii( "ALTER TABLE ONLY"); +// bufferQuoteQualifiedIdentifier( update, m_schemaName, m_tableName ); +// update.appendAscii( "DROP COLUMN" ); +// bufferQuoteIdentifier( update, name ); +// Reference< XStatement > stmt = m_origin->createStatement( ); +// DisposeGuard disposeIt( stmt ); +// stmt->executeUpdate( update.makeStringAndClear() ); + +} + + +Reference< ::com::sun::star::beans::XPropertySet > KeyColumns::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new KeyColumnDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +Reference< com::sun::star::container::XNameAccess > KeyColumns::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + const Sequence< rtl::OUString > &columnNames , + const Sequence< rtl::OUString > &foreignColumnNames ) +{ + KeyColumns *pKeyColumns = new KeyColumns( + refMutex, origin, pSettings, schemaName, tableName, columnNames, foreignColumnNames ); + Reference< com::sun::star::container::XNameAccess > ret = pKeyColumns; + pKeyColumns->refresh(); + + return ret; +} + +//_______________________________________________________________________________________ +KeyColumnDescriptors::KeyColumnDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ) + : Container( refMutex, origin, pSettings, ASCII_STR( "KEY_COLUMN" ) ) +{} + +Reference< ::com::sun::star::beans::XPropertySet > KeyColumnDescriptors::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new KeyColumnDescriptor( m_refMutex, m_origin, m_pSettings ); +} +}; diff --git connectivity/source/drivers/postgresql/pq_xkeycolumns.hxx connectivity/source/drivers/postgresql/pq_xkeycolumns.hxx new file mode 100644 index 0000000..ae0f001 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xkeycolumns.hxx @@ -0,0 +1,134 @@ +/************************************************************************* + * + * $RCSfile: pq_xkeycolumns.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:09 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_KEYCOLUMNS_HXX +#define HEADER_PQ_KEYCOLUMNS_HXX + +#include "pq_xcontainer.hxx" + +namespace pq_sdbc_driver +{ + +class KeyColumns : public Container +{ + rtl::OUString m_schemaName; + rtl::OUString m_tableName; + com::sun::star::uno::Sequence< rtl::OUString > m_columnNames; + com::sun::star::uno::Sequence< rtl::OUString > m_foreignColumnNames; + +public: // instances KeyColumns 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + const com::sun::star::uno::Sequence< rtl::OUString > &keyColumns, + const com::sun::star::uno::Sequence< rtl::OUString > &foreignColumnNames ); + +protected: + KeyColumns( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName, + const com::sun::star::uno::Sequence< rtl::OUString > &keyColumns, + const com::sun::star::uno::Sequence< rtl::OUString > &foreignColumnNames); + + virtual ~KeyColumns(); + +public: // XAppend + virtual void SAL_CALL appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +public: // XDrop + virtual void SAL_CALL dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // XRefreshable + virtual void SAL_CALL refresh( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); +}; + + +class KeyColumnDescriptors : public Container +{ +public: + KeyColumnDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); +}; +} +#endif diff --git connectivity/source/drivers/postgresql/pq_xkeys.cxx connectivity/source/drivers/postgresql/pq_xkeys.cxx new file mode 100644 index 0000000..2b7b540 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xkeys.cxx @@ -0,0 +1,387 @@ +/************************************************************************* + * + * $RCSfile: pq_xkeys.cxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2004/08/29 08:33:32 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "pq_xkeys.hxx" +#include "pq_xkey.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::beans::XPropertySet; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::container::NoSuchElementException; +using com::sun::star::lang::WrappedTargetException; + +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XDatabaseMetaData; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +Keys::Keys( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName) + : Container( refMutex, origin, pSettings, getStatics().KEY ), + m_schemaName( schemaName ), + m_tableName( tableName ) +{} + +Keys::~Keys() +{} + +static sal_Int32 string2keytype( const rtl::OUString &type ) +{ + sal_Int32 ret = com::sun::star::sdbcx::KeyType::UNIQUE; + if( type.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "p" ) ) == 0 ) + ret = com::sun::star::sdbcx::KeyType::PRIMARY; + else if( type.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "f" ) ) == 0 ) + ret = com::sun::star::sdbcx::KeyType::FOREIGN; + return ret; +} + +static sal_Int32 string2keyrule( const rtl::OUString & rule ) +{ + sal_Int32 ret = com::sun::star::sdbc::KeyRule::NO_ACTION; + if( rule.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "r" ) ) == 0 ) + ret = com::sun::star::sdbc::KeyRule::RESTRICT; + else if( rule.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "c" ) ) == 0 ) + ret = com::sun::star::sdbc::KeyRule::CASCADE; + else if( rule.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "n" ) ) == 0 ) + ret = com::sun::star::sdbc::KeyRule::SET_NULL; + else if( rule.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "d" ) ) == 0 ) + ret = com::sun::star::sdbc::KeyRule::SET_DEFAULT; + return ret; +} + + + +// static void fillAttnum2attnameMap( +// Int2StringMap &map, +// const Reference< com::sun::star::sdbc::XConnection > &conn, +// const rtl::OUString &schema, +// const rtl::OUString &table ) +// { +// Reference< XPreparedStatement > prep = conn->prepareStatement( +// ASCII_STR( "SELECT attname,attnum " +// "FROM pg_attribute " +// "INNER JOIN pg_class ON attrelid = pg_class.oid " +// "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid " +// "WHERE relname=? AND nspname=?" ) ); + +// Reference< XParameters > paras( prep, UNO_QUERY ); +// paras->setString( 1 , table ); +// paras->setString( 2 , schema ); +// Reference< XResultSet > rs = prep->executeQuery(); + +// Reference< XRow > xRow( rs , UNO_QUERY ); +// while( rs->next() ) +// { +// map[ xRow->getInt(2) ] = xRow->getString(1); +// } +// } + +// static Sequence< rtl::OUString > resolveColumnNames( +// const Int2StringMap &map, const rtl::OUString &array ) +// { +// Sequence< sal_Int32 > intArray = string2intarray( array ); +// Sequence< ::rtl::OUString > ret( intArray.getLength() ); +// for( int i = 0; i < intArray.getLength() ; i ++ ) +// { +// Int2StringMap::const_iterator ii = map.find( intArray[i] ); +// if( ii != map.end() ) +// ret[i] = ii->second; +// } +// return ret; +// } + +void Keys::refresh() + throw (::com::sun::star::uno::RuntimeException) +{ + try + { + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + rtl::OStringBuffer buf; + buf.append( "sdbcx.Keys get refreshed for table " ); + buf.append( OUStringToOString( m_schemaName, m_pSettings->encoding ) ); + buf.append( "." ); + buf.append( OUStringToOString( m_tableName,m_pSettings->encoding ) ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() ); + } + + osl::MutexGuard guard( m_refMutex->mutex ); + Statics & st = getStatics(); + + Int2StringMap mainMap; + fillAttnum2attnameMap( mainMap, m_origin, m_schemaName, m_tableName ); + + Reference< XPreparedStatement > stmt = m_origin->prepareStatement( + ASCII_STR( + "SELECT conname, " // 1 + "contype, " // 2 + "confupdtype, " // 3 + "confdeltype, " // 4 + "class2.relname, " // 5 + "nmsp2.nspname, " // 6 + "conkey," // 7 + "confkey " // 8 + "FROM pg_constraint INNER JOIN pg_class ON conrelid = pg_class.oid " + "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid " + "LEFT JOIN pg_class AS class2 ON confrelid = class2.oid " + "LEFT JOIN pg_namespace AS nmsp2 ON class2.relnamespace=nmsp2.oid " + "WHERE pg_class.relname = ? AND pg_namespace.nspname = ?" ) ); + + Reference< XParameters > paras( stmt, UNO_QUERY ); + paras->setString( 1 , m_tableName ); + paras->setString( 2 , m_schemaName ); + Reference< XResultSet > rs = stmt->executeQuery(); + + Reference< XRow > xRow( rs , UNO_QUERY ); + + String2IntMap map; + std::vector< Any, Allocator< Any> > vec; + sal_Int32 keyIndex = 0; + while( rs->next() ) + { + Key * pKey = + new Key( m_refMutex, m_origin, m_pSettings , m_schemaName, m_tableName ); + Reference< com::sun::star::beans::XPropertySet > prop = pKey; + + pKey->setPropertyValue_NoBroadcast_public( + st.NAME, makeAny( xRow->getString( 1 ) ) ); + sal_Int32 keyType = string2keytype( xRow->getString(2) ); + pKey->setPropertyValue_NoBroadcast_public( st.TYPE, makeAny( keyType ) ); + pKey->setPropertyValue_NoBroadcast_public( + st.UPDATE_RULE, makeAny( string2keyrule( xRow->getString(3) ) ) ); + pKey->setPropertyValue_NoBroadcast_public( + st.DELETE_RULE, makeAny( string2keyrule( xRow->getString(4) ) ) ); + pKey->setPropertyValue_NoBroadcast_public( + st.PRIVATE_COLUMNS, + makeAny( + convertMappedIntArray2StringArray( + mainMap, + string2intarray( xRow->getString( 7 ) ) ) ) ); + + if( com::sun::star::sdbcx::KeyType::FOREIGN == keyType ) + { + OUStringBuffer buf( 128 ); + buf.append( xRow->getString( 6 ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "." ) ); + buf.append( xRow->getString( 5 ) ); + pKey->setPropertyValue_NoBroadcast_public( + st.REFERENCED_TABLE, makeAny( buf.makeStringAndClear() ) ); + + Int2StringMap foreignMap; + fillAttnum2attnameMap( foreignMap, m_origin, xRow->getString(6), xRow->getString(5)); + pKey->setPropertyValue_NoBroadcast_public( + st.PRIVATE_FOREIGN_COLUMNS, + makeAny( + convertMappedIntArray2StringArray( + foreignMap, + string2intarray( xRow->getString(8) ) ) ) ); + } + + vec.push_back( makeAny( prop ) ); + map[ xRow->getString( 1 ) ] = keyIndex; + keyIndex ++; + } + m_values = Sequence< com::sun::star::uno::Any > ( & vec[0] , vec.size() ); + m_name2index.swap( map ); + } + catch ( com::sun::star::sdbc::SQLException & e ) + { + throw RuntimeException( e.Message , e.Context ); + } + + fire( RefreshedBroadcaster( *this ) ); +} + + +void Keys::appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE " ) ); + bufferQuoteQualifiedIdentifier( buf, m_schemaName, m_tableName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ADD " ) ); + bufferKey2TableConstraint( buf, descriptor ); + + Reference< XStatement > stmt = + m_origin->createStatement(); + stmt->executeUpdate( buf.makeStringAndClear() ); +} + + +void Keys::dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + if( index < 0 || index >= m_values.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "TABLES: Index out of range (allowed 0 to " ); + buf.append( (sal_Int32)(m_values.getLength() -1) ); + buf.appendAscii( ", got " ); + buf.append( index ); + buf.appendAscii( ")" ); + throw com::sun::star::lang::IndexOutOfBoundsException( + buf.makeStringAndClear(), *this ); + } + + + Reference< XPropertySet > set; + m_values[index] >>= set; + + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE " ) ); + bufferQuoteQualifiedIdentifier( buf, m_schemaName, m_tableName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " DROP CONSTRAINT " ) ); + bufferQuoteIdentifier( buf, extractStringProperty( set , getStatics().NAME ) ); + m_origin->createStatement()->executeUpdate( buf.makeStringAndClear() ); + + + Container::dropByIndex( index ); +} + + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Keys::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new KeyDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +Reference< com::sun::star::container::XIndexAccess > Keys::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString & schemaName, + const rtl::OUString & tableName) +{ + Keys *pKeys = new Keys( refMutex, origin, pSettings, schemaName, tableName ); + Reference< com::sun::star::container::XIndexAccess > ret = pKeys; + pKeys->refresh(); + + return ret; +} +//_________________________________________________________________________________________ +KeyDescriptors::KeyDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings) + : Container( refMutex, origin, pSettings, getStatics().KEY ) +{} + +Reference< com::sun::star::container::XIndexAccess > KeyDescriptors::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings) +{ + return new KeyDescriptors( refMutex, origin, pSettings ); +} + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > KeyDescriptors::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new KeyDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +}; diff --git connectivity/source/drivers/postgresql/pq_xkeys.hxx connectivity/source/drivers/postgresql/pq_xkeys.hxx new file mode 100644 index 0000000..c996222 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xkeys.hxx @@ -0,0 +1,134 @@ +/************************************************************************* + * + * $RCSfile: pq_xkeys.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_KEYS_HXX_ +#define _PQ_KEYS_HXX_ + +#include "pq_xcontainer.hxx" + +namespace pq_sdbc_driver +{ +class Keys : public Container +{ + rtl::OUString m_schemaName; + rtl::OUString m_tableName; + +public: // instances Columns 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName); + +protected: + Keys( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + const rtl::OUString &schemaName, + const rtl::OUString &tableName); + + virtual ~Keys(); + +public: // XAppend + virtual void SAL_CALL appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +public: // XDrop + virtual void SAL_CALL dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // XRefreshable + virtual void SAL_CALL refresh( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); +}; + + +class KeyDescriptors : public Container +{ +public: // instances Columns 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ); + +protected: + KeyDescriptors( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_xtable.cxx connectivity/source/drivers/postgresql/pq_xtable.cxx new file mode 100644 index 0000000..50871a1 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xtable.cxx @@ -0,0 +1,484 @@ +/************************************************************************* + * + * $RCSfile: pq_xtable.cxx,v $ + * + * $Revision: 1.1.2.6 $ + * + * last change: $Author: jbu $ $Date: 2007/01/07 13:50:38 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "pq_xtable.hxx" +#include "pq_xtables.hxx" +#include "pq_xviews.hxx" +#include "pq_xindexes.hxx" +#include "pq_xkeys.hxx" +#include "pq_xcolumns.hxx" +#include "pq_tools.hxx" +#include "pq_statics.hxx" + +using osl::MutexGuard; +using osl::Mutex; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::container::XNameAccess; +using com::sun::star::container::XIndexAccess; +using com::sun::star::container::ElementExistException; +using com::sun::star::container::NoSuchElementException; + +using com::sun::star::uno::Reference; +using com::sun::star::uno::Exception; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::lang::IllegalArgumentException; +using com::sun::star::lang::IndexOutOfBoundsException; + +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::XFastPropertySet; +using com::sun::star::beans::XMultiPropertySet; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::Property; + +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::SQLException; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +Table::Table( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings) + : ReflectionBase( + getStatics().refl.table.implName, + getStatics().refl.table.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.table.pProps ), + m_pColumns( 0 ) +{} + +Reference< XPropertySet > Table::createDataDescriptor( ) throw (RuntimeException) +{ + TableDescriptor * pTable = new TableDescriptor( + m_refMutex, m_conn, m_pSettings ); + pTable->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pTable ); +} + +Reference< XNameAccess > Table::getColumns( ) throw (::com::sun::star::uno::RuntimeException) +{ + if( ! m_columns.is() ) + { + m_columns = Columns::create( + m_refMutex, + m_conn, + m_pSettings, + extractStringProperty( this, getStatics().SCHEMA_NAME ), + extractStringProperty( this, getStatics().NAME ), + &m_pColumns); + } + return m_columns; +} + +Reference< XNameAccess > Table::getIndexes() throw (::com::sun::star::uno::RuntimeException) +{ + if( ! m_indexes.is() ) + { + m_indexes = ::pq_sdbc_driver::Indexes::create( + m_refMutex, + m_conn, + m_pSettings, + extractStringProperty( this, getStatics().SCHEMA_NAME ), + extractStringProperty( this, getStatics().NAME ) ); + } + return m_indexes; +} + +Reference< XIndexAccess > Table::getKeys( ) throw (::com::sun::star::uno::RuntimeException) +{ + if( ! m_keys.is() ) + { + m_keys = ::pq_sdbc_driver::Keys::create( + m_refMutex, + m_conn, + m_pSettings, + extractStringProperty( this, getStatics().SCHEMA_NAME ), + extractStringProperty( this, getStatics().NAME ) ); + } + return m_keys; +} + +void Table::rename( const ::rtl::OUString& newName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + Statics & st = getStatics(); + + ::rtl::OUString oldName = extractStringProperty(this,st.NAME ); + ::rtl::OUString schema = extractStringProperty(this,st.SCHEMA_NAME ); + ::rtl::OUString fullOldName = concatQualified( schema, oldName ); + + OUString newTableName; + OUString newSchemaName; + // OOo2.0 passes schema + dot + new-table-name while + // OO1.1.x passes new Name without schema + // in case name contains a dot, it is interpreted as schema.tablename + if( newName.indexOf( '.' ) >= 0 ) + { + splitConcatenatedIdentifier( newName, &newSchemaName, &newTableName ); + } + else + { + newTableName = newName; + newSchemaName = schema; + } + ::rtl::OUString fullNewName = concatQualified( newSchemaName, newTableName ); + + if( extractStringProperty( this, st.TYPE ).equals( st.VIEW ) && m_pSettings->views.is() ) + { + // maintain view list (really strange API !) + Any a = m_pSettings->pViewsImpl->getByName( fullOldName ); + Reference< com::sun::star::sdbcx::XRename > rename; + a >>= rename; + if( rename.is() ) + { + rename->rename( newName ); + setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME, makeAny(newSchemaName) ); + } + } + else + { + if( ! newSchemaName.equals(schema) ) + { + // try new schema name first + try + { + OUStringBuffer buf(128); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); + bufferQuoteQualifiedIdentifier(buf, schema, oldName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("SET SCHEMA" ) ); + bufferQuoteIdentifier( buf, newSchemaName ); + Reference< XStatement > statement = m_conn->createStatement(); + statement->executeUpdate( buf.makeStringAndClear() ); + setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME, makeAny(newSchemaName) ); + disposeNoThrow( statement ); + schema = newSchemaName; + } + catch( com::sun::star::sdbc::SQLException &e ) + { + OUStringBuffer buf( e.Message ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "(NOTE: Only postgresql server >= V8.1 support changing a table's schema)" ) ); + e.Message = buf.makeStringAndClear(); + throw e; + } + + } + if( ! newTableName.equals( oldName ) ) // might also be just the change of a schema name + { + OUStringBuffer buf(128); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); + bufferQuoteQualifiedIdentifier(buf, schema, oldName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("RENAME TO" ) ); + bufferQuoteIdentifier( buf, newTableName ); + Reference< XStatement > statement = m_conn->createStatement(); + statement->executeUpdate( buf.makeStringAndClear() ); + disposeNoThrow( statement ); + } + } + setPropertyValue_NoBroadcast_public( st.NAME, makeAny(newTableName) ); + // inform the container of the name change ! + if( m_pSettings->tables.is() ) + { + m_pSettings->pTablesImpl->rename( fullOldName, fullNewName ); + } +} + +void Table::alterColumnByName( + const ::rtl::OUString& colName, + const Reference< XPropertySet >& descriptor ) + throw (SQLException,NoSuchElementException,RuntimeException) +{ + Reference< com::sun::star::container::XNameAccess > colums = + Reference< com::sun::star::container::XNameAccess > ( getColumns(), UNO_QUERY ); + + OUString newName = extractStringProperty(descriptor, getStatics().NAME ); + ::pq_sdbc_driver::alterColumnByDescriptor( + extractStringProperty( this, getStatics().SCHEMA_NAME ), + extractStringProperty( this, getStatics().NAME ), + m_pSettings->encoding, + m_conn->createStatement(), + Reference< com::sun::star::beans::XPropertySet>( colums->getByName( colName ), UNO_QUERY) , + descriptor ); + + if( colName != newName ) + { +// m_pColumns->rename( colName, newName ); + m_pColumns->refresh(); + } +} + +void Table::alterColumnByIndex( + sal_Int32 index, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (SQLException,IndexOutOfBoundsException,RuntimeException) +{ + Reference< com::sun::star::container::XIndexAccess > colums = + Reference< com::sun::star::container::XIndexAccess>( getColumns(), UNO_QUERY ); + Reference< com::sun::star::beans::XPropertySet> column(colums->getByIndex( index ), UNO_QUERY ); + OUString oldName = extractStringProperty( column, getStatics().NAME ); + OUString newName = extractStringProperty( descriptor, getStatics().NAME ); + ::pq_sdbc_driver::alterColumnByDescriptor( + extractStringProperty( this, getStatics().SCHEMA_NAME ), + extractStringProperty( this, getStatics().NAME ), + m_pSettings->encoding, + m_conn->createStatement(), + column, + descriptor ); +// m_pColumns->rename( oldName, newName ); + m_pColumns->refresh(); +} + +Sequence Table::getTypes() throw( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< com::sun::star::sdbcx::XIndexesSupplier> *) 0 ), + getCppuType( (Reference< com::sun::star::sdbcx::XKeysSupplier> *) 0 ), + getCppuType( (Reference< com::sun::star::sdbcx::XColumnsSupplier> *) 0 ), + getCppuType( (Reference< com::sun::star::sdbcx::XRename> *) 0 ), + getCppuType( (Reference< com::sun::star::sdbcx::XAlterTable> *) 0 ), + ReflectionBase::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> Table::getImplementationId() throw( RuntimeException ) +{ + return getStatics().refl.table.implementationId; +} + +Any Table::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = ReflectionBase::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< com::sun::star::sdbcx::XIndexesSupplier * > ( this ), + static_cast< com::sun::star::sdbcx::XKeysSupplier * > ( this ), + static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this ), + static_cast< com::sun::star::sdbcx::XRename * > ( this ), + static_cast< com::sun::star::sdbcx::XAlterTable * > ( this ) + ); + return ret; +} + +::com::sun::star::uno::Any Table::getPropertyValue(const ::rtl::OUString& aPropertyName) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + return ReflectionBase::getPropertyValue( aPropertyName ); +} + + +::rtl::OUString Table::getName( ) throw (::com::sun::star::uno::RuntimeException) +{ + Statics & st = getStatics(); + return concatQualified( + extractStringProperty( this, st.SCHEMA_NAME ), + extractStringProperty( this, st.NAME ) ); +} + +void Table::setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException) +{ + rename( aName ); +} + + + +//________________________________________________________________________ +TableDescriptor::TableDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings) + : ReflectionBase( + getStatics().refl.tableDescriptor.implName, + getStatics().refl.tableDescriptor.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.tableDescriptor.pProps ) +{ +} + +Reference< XNameAccess > TableDescriptor::getColumns( ) throw (::com::sun::star::uno::RuntimeException) +{ + if( ! m_columns.is() ) + { + m_columns = new ColumnDescriptors(m_refMutex, m_conn, m_pSettings ); + } + return m_columns; +} + +Reference< XNameAccess > TableDescriptor::getIndexes() throw (::com::sun::star::uno::RuntimeException) +{ + if( ! m_indexes.is() ) + { + m_indexes = ::pq_sdbc_driver::IndexDescriptors::create( + m_refMutex, + m_conn, + m_pSettings); + } + return m_indexes; +} + +Reference< XIndexAccess > TableDescriptor::getKeys( ) throw (::com::sun::star::uno::RuntimeException) +{ + if( ! m_keys.is() ) + { + m_keys = ::pq_sdbc_driver::KeyDescriptors::create( + m_refMutex, + m_conn, + m_pSettings ); + } + return m_keys; +} + + +Sequence TableDescriptor::getTypes() throw( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< com::sun::star::sdbcx::XIndexesSupplier> *) 0 ), + getCppuType( (Reference< com::sun::star::sdbcx::XKeysSupplier> *) 0 ), + getCppuType( (Reference< com::sun::star::sdbcx::XColumnsSupplier> *) 0 ), + ReflectionBase::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> TableDescriptor::getImplementationId() throw( RuntimeException ) +{ + return getStatics().refl.tableDescriptor.implementationId; +} + +Any TableDescriptor::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = ReflectionBase::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< com::sun::star::sdbcx::XIndexesSupplier * > ( this ), + static_cast< com::sun::star::sdbcx::XKeysSupplier * > ( this ), + static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this )); + return ret; +} + + +Reference< XPropertySet > TableDescriptor::createDataDescriptor( ) throw (RuntimeException) +{ + TableDescriptor * pTable = new TableDescriptor( + m_refMutex, m_conn, m_pSettings ); + + // TODO: deep copies + pTable->m_values = m_values; + + return Reference< XPropertySet > ( pTable ); +} + +} diff --git connectivity/source/drivers/postgresql/pq_xtable.hxx connectivity/source/drivers/postgresql/pq_xtable.hxx new file mode 100644 index 0000000..4a7e25c --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xtable.hxx @@ -0,0 +1,220 @@ +/************************************************************************* + * + * $RCSfile: pq_xtable.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_TABLE_HXX_ +#define _PQ_TABLE_HXX_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pq_xbase.hxx" + +namespace pq_sdbc_driver +{ + +class Columns; + +class Table : public ReflectionBase, + public com::sun::star::sdbcx::XColumnsSupplier, + public com::sun::star::sdbcx::XIndexesSupplier, + public com::sun::star::sdbcx::XKeysSupplier, + public com::sun::star::sdbcx::XRename, + public com::sun::star::sdbcx::XAlterTable +{ + ::com::sun::star::uno::Reference< com::sun::star::sdbc::XDatabaseMetaData > m_meta; + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_columns; + ::com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess > m_keys; + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_indexes; + Columns *m_pColumns; + +public: + Table( const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); +public: + void refetch(); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XColumnsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL + getColumns( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XIndexesSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL + getIndexes( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XKeysSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL + getKeys( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XRename + virtual void SAL_CALL rename( const ::rtl::OUString& newName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +public: // XAlterTable + // Methods + virtual void SAL_CALL alterColumnByName( + const ::rtl::OUString& colName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL alterColumnByIndex( + sal_Int32 index, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // TODO: remove again + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue(const ::rtl::OUString& aPropertyName) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + +public: // XNamed + virtual ::rtl::OUString SAL_CALL getName( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); +}; + + + +class TableDescriptor + : public ReflectionBase, + public com::sun::star::sdbcx::XColumnsSupplier, + public com::sun::star::sdbcx::XIndexesSupplier, + public com::sun::star::sdbcx::XKeysSupplier +{ + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_columns; + ::com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess > m_keys; + ::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_indexes; + +public: + TableDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XColumnsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL + getColumns( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XIndexesSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL + getIndexes( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XKeysSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL + getKeys( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); +}; + + +void copyProperties( + ReflectionBase *target, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > & source ); + +} + + +#endif diff --git connectivity/source/drivers/postgresql/pq_xtables.cxx connectivity/source/drivers/postgresql/pq_xtables.cxx new file mode 100644 index 0000000..90a5786 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xtables.cxx @@ -0,0 +1,464 @@ +/************************************************************************* + * + * $RCSfile: pq_xtables.cxx,v $ + * + * $Revision: 1.1.2.4 $ + * + * last change: $Author: jbu $ $Date: 2006/05/01 19:19:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "pq_xtables.hxx" +#include "pq_xviews.hxx" +#include "pq_xtable.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::beans::XPropertySet; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::container::NoSuchElementException; +using com::sun::star::container::XEnumerationAccess; +using com::sun::star::container::XEnumeration; +using com::sun::star::lang::WrappedTargetException; + +using com::sun::star::sdbc::XRow; +// using com::sun::star::sdbc::DataType; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XDatabaseMetaData; +using com::sun::star::sdbcx::XColumnsSupplier; +using com::sun::star::sdbcx::XKeysSupplier; +using com::sun::star::sdbcx::XViewsSupplier; +// using com::sun::star::sdbcx::Privilege; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) +Tables::Tables( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ) + : Container( refMutex, origin, pSettings, getStatics().TABLE ) +{} + +Tables::~Tables() +{} + +void Tables::refresh() + throw (::com::sun::star::uno::RuntimeException) +{ + try + { + osl::MutexGuard guard( m_refMutex->mutex ); + Statics & st = getStatics(); + + Reference< XDatabaseMetaData > meta = m_origin->getMetaData(); + + Reference< XResultSet > rs = + meta->getTables( Any(), st.cPERCENT,st.cPERCENT, Sequence< OUString > () ); + + Reference< XRow > xRow( rs , UNO_QUERY ); + + String2IntMap map; + + std::vector< Any, Allocator< Any> > vec; + sal_Int32 tableIndex = 0; + while( rs->next() ) + { + // if creating all these tables turns out to have too bad performance, we might + // instead offer a factory interface + Table * pTable = + new Table( m_refMutex, m_origin, m_pSettings ); + Reference< com::sun::star::beans::XPropertySet > prop = pTable; + + OUString name = xRow->getString( TABLE_INDEX_NAME+1); + OUString schema = xRow->getString( TABLE_INDEX_SCHEMA+1); + pTable->setPropertyValue_NoBroadcast_public( + st.CATALOG_NAME , makeAny(xRow->getString( TABLE_INDEX_CATALOG+1) ) ); + pTable->setPropertyValue_NoBroadcast_public( st.NAME , makeAny( name ) ); + pTable->setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME , makeAny( schema )); + pTable->setPropertyValue_NoBroadcast_public( + st.TYPE , makeAny( xRow->getString( TABLE_INDEX_TYPE+1) ) ); + pTable->setPropertyValue_NoBroadcast_public( + st.DESCRIPTION , makeAny( xRow->getString( TABLE_INDEX_REMARKS+1) ) ); + pTable->setPropertyValue_NoBroadcast_public( + st.PRIVILEGES , + makeAny( (sal_Int32) + ( com::sun::star::sdbcx::Privilege::SELECT | + com::sun::star::sdbcx::Privilege::INSERT | + com::sun::star::sdbcx::Privilege::UPDATE | + com::sun::star::sdbcx::Privilege::DELETE | + com::sun::star::sdbcx::Privilege::READ | + com::sun::star::sdbcx::Privilege::CREATE | + com::sun::star::sdbcx::Privilege::ALTER | + com::sun::star::sdbcx::Privilege::REFERENCE | + com::sun::star::sdbcx::Privilege::DROP ) ) ); + + vec.push_back( makeAny( prop ) ); + OUStringBuffer buf( name.getLength() + schema.getLength() + 1); + buf.append( schema ).appendAscii( "." ).append( name ); + map[ buf.makeStringAndClear() ] = tableIndex; + tableIndex ++; + } + m_values = Sequence< com::sun::star::uno::Any > ( & vec[0] , vec.size() ); + m_name2index.swap( map ); + } + catch ( com::sun::star::sdbc::SQLException & e ) + { + throw RuntimeException( e.Message , e.Context ); + } + + fire( RefreshedBroadcaster( *this ) ); +} + + +static void appendColumnList( + OUStringBuffer &buf, const Reference< XColumnsSupplier > & columnSupplier, sal_Int32 encoding ) +{ + if( columnSupplier.is() ) + { + Reference< XEnumerationAccess > columns( columnSupplier->getColumns(),UNO_QUERY ); + if( columns.is() ) + { + Reference< XEnumeration > xEnum( columns->createEnumeration() ); + bool first = true; + Statics & st = getStatics(); + + while( xEnum.is() && xEnum->hasMoreElements() ) + { + if( first ) + { + first = false; + } + else + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) ); + } + Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY ); + OUString name = extractStringProperty( column, st.NAME ); + OUString defaultValue = extractStringProperty( column, st.DEFAULT_VALUE ); + sal_Bool isNullable = extractBoolProperty( column, st.IS_NULLABLE ); + sal_Bool isAutoIncrement = extractBoolProperty( column, st.IS_AUTO_INCREMENT ); + + bufferQuoteIdentifier( buf, name ); + + OUString type = sqltype2string( column ); + if( isAutoIncrement ) + { + sal_Int32 dataType; + column->getPropertyValue( st.TYPE ) >>= dataType; + if( com::sun::star::sdbc::DataType::INTEGER == dataType ) + { + buf.appendAscii( " serial "); + isNullable = sal_False; + } + else if( com::sun::star::sdbc::DataType::BIGINT == dataType ) + { + buf.appendAscii( " serial8 " ); + isNullable = sal_False; + } + else + buf.append( type ); + } + else + { + buf.append( type ); + } + if( defaultValue.getLength() ) + { + bufferQuoteConstant( buf, defaultValue, encoding ); + } + + if( ! isNullable ) +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " NULL " ) ); +// else + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " NOT NULL " ) ); + + } + } + } +} + +static void appendKeyList( + OUStringBuffer & buf, const Reference< XKeysSupplier > &keySupplier ) +{ + if( keySupplier.is() ) + { + Reference< XEnumerationAccess > keys( keySupplier->getKeys(), UNO_QUERY ); + if(keys.is() ) + { + Statics &st = getStatics(); + Reference< XEnumeration > xEnum = keys->createEnumeration(); + while( xEnum.is() && xEnum->hasMoreElements() ) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) ); + Reference< XPropertySet > key( xEnum->nextElement(), UNO_QUERY ); + bufferKey2TableConstraint( buf, key ); + } + } + } +} + +void Tables::appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + Reference< XStatement > stmt = + m_origin->createStatement(); + + Statics &st = getStatics(); + OUString name,schema; + descriptor->getPropertyValue( st.SCHEMA_NAME ) >>= schema; + descriptor->getPropertyValue( st.NAME ) >>= name; + + TransactionGuard transaction( stmt ); + + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("CREATE TABLE" ) ); + bufferQuoteQualifiedIdentifier( buf, schema, name ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "(" ) ); + + // columns + Reference< XColumnsSupplier > supplier( descriptor, UNO_QUERY ); + appendColumnList( buf, supplier, m_pSettings->encoding ); + + appendKeyList( buf, Reference< XKeysSupplier >( descriptor, UNO_QUERY ) ); + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ") " ) ); + // execute the creation ! + transaction.executeUpdate( buf.makeStringAndClear() ); + + // description .... + OUString description = extractStringProperty( descriptor, st.DESCRIPTION ); + if( description.getLength() ) + { + buf = OUStringBuffer( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "COMMENT ON TABLE" ) ); + bufferQuoteQualifiedIdentifier( buf, schema, name ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "IS " ) ); + bufferQuoteConstant( buf, description, m_pSettings->encoding ); + + transaction.executeUpdate( buf.makeStringAndClear() ); + } + + // column descriptions + if( supplier.is() ) + { + Reference< XEnumerationAccess > columns( supplier->getColumns(),UNO_QUERY ); + if( columns.is() ) + { + Reference< XEnumeration > xEnum( columns->createEnumeration() ); + while( xEnum.is() && xEnum->hasMoreElements() ) + { + Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY ); + // help text seems to be used by OOo rather than Description +// OUString description = extractStringProperty( column, st.HELP_TEXT ); + OUString helpText = extractStringProperty( column,st.DESCRIPTION ); + if( description.getLength() ) + { + buf = OUStringBuffer( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "COMMENT ON COLUMN " ) ); + bufferQuoteQualifiedIdentifier( + buf, schema, name, extractStringProperty( column, st.NAME ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "IS " ) ); + bufferQuoteConstant( + buf, description,m_pSettings->encoding ); + transaction.executeUpdate( buf.makeStringAndClear() ); + } + } + } + } + + transaction.commit(); + + disposeNoThrow( stmt ); + // TODO: cheaper recalculate +// Container::append( concatQualified( schema, name ), descriptor ); // maintain the lists + refresh(); + + // increase the vector +// sal_Int32 index = m_values.getLength(); +// m_values.realloc( index + 1 ); + +// Table * pTable = +// new Table( m_refMutex, m_origin, m_pSettings, false /*modifiable*/ ); +// Reference< com::sun::star::beans::XPropertySet > prop = pTable; +// copyProperties( pTable, descriptor ); +// m_values[index] = makeAny( prop ); +// OUStringBuffer buf( name.getLength() + 1 + schema.getLength() ); +// buf.append( schema ).appendAscii( "." ).append( name ); +// m_name2index[ buf.makeStringAndClear() ] = index; +} + +// void Tables::dropByName( const ::rtl::OUString& elementName ) +// throw (::com::sun::star::sdbc::SQLException, +// ::com::sun::star::container::NoSuchElementException, +// ::com::sun::star::uno::RuntimeException) +// { +// String2IntMap::const_iterator ii = m_name2index.find( elementName ); +// if( ii == m_name2index.end() ) +// { +// OUStringBuffer buf( 128 ); +// buf.appendAscii( "Table " ); +// buf.append( elementName ); +// buf.appendAscii( " is unknown, so it can't be dropped" ); +// throw com::sun::star::container::NoSuchElementException( +// buf.makeStringAndClear(), *this ); +// } +// dropByIndex( ii->second ); +// } + +void Tables::dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + if( index < 0 || index >= m_values.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "TABLES: Index out of range (allowed 0 to " ); + buf.append( (sal_Int32) (m_values.getLength() -1) ); + buf.appendAscii( ", got " ); + buf.append( index ); + buf.appendAscii( ")" ); + throw com::sun::star::lang::IndexOutOfBoundsException( + buf.makeStringAndClear(), *this ); + } + + Reference< XPropertySet > set; + m_values[index] >>= set; + Statics &st = getStatics(); + OUString name,schema; + set->getPropertyValue( st.SCHEMA_NAME ) >>= schema; + set->getPropertyValue( st.NAME ) >>= name; + if( extractStringProperty( set, st.TYPE ).equals( st.VIEW ) && m_pSettings->views.is() ) + { + m_pSettings->pViewsImpl->dropByName( concatQualified( schema, name ) ); + } + else + { + OUStringBuffer update( 128 ); + update.appendAscii( RTL_CONSTASCII_STRINGPARAM( "DROP " ) ); + if( extractStringProperty( set, st.TYPE ).equals( st.VIEW ) ) + update.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VIEW " ) ); + else + update.appendAscii( RTL_CONSTASCII_STRINGPARAM( "TABLE " ) ); + bufferQuoteQualifiedIdentifier( update, schema, name ); + Reference< XStatement > stmt = m_origin->createStatement( ); + DisposeGuard dispGuard( stmt ); + stmt->executeUpdate( update.makeStringAndClear() ); + } + + Container::dropByIndex( index ); +} + + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Tables::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new TableDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +Reference< com::sun::star::container::XNameAccess > Tables::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + Tables **ppTables) +{ + *ppTables = new Tables( refMutex, origin, pSettings ); + Reference< com::sun::star::container::XNameAccess > ret = *ppTables; + (*ppTables)->refresh(); + + return ret; +} + +void Tables::disposing() +{ + Container::disposing(); +} + +}; diff --git connectivity/source/drivers/postgresql/pq_xtables.hxx connectivity/source/drivers/postgresql/pq_xtables.hxx new file mode 100644 index 0000000..c14fe77 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xtables.hxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * $RCSfile: pq_xtables.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:11 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_TABLES_HXX_ +#define _PQ_TABLES_HXX_ + +#include "pq_xcontainer.hxx" + +namespace pq_sdbc_driver +{ + +class Tables : public Container +{ + +public: // instances Tables 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + Tables ** ppTables); + +protected: + Tables( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ); + + virtual ~Tables(); + +public: // XAppend + virtual void SAL_CALL appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +public: // XDrop +// virtual void SAL_CALL dropByName( const ::rtl::OUString& elementName ) +// throw (::com::sun::star::sdbc::SQLException, +// ::com::sun::star::container::NoSuchElementException, +// ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // XRefreshable + virtual void SAL_CALL refresh( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); + +protected: + virtual void SAL_CALL disposing(); + +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_xuser.cxx connectivity/source/drivers/postgresql/pq_xuser.cxx new file mode 100644 index 0000000..0fe46f6 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xuser.cxx @@ -0,0 +1,257 @@ +/************************************************************************* + * + * $RCSfile: pq_xuser.cxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: jbu $ $Date: 2006/01/22 15:14:40 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "pq_xuser.hxx" +#include "pq_tools.hxx" +#include "pq_statics.hxx" + +using osl::MutexGuard; +using osl::Mutex; + +using rtl::OUString; +using rtl::OUStringBuffer; + +using com::sun::star::container::XNameAccess; +using com::sun::star::container::XIndexAccess; +using com::sun::star::container::ElementExistException; +using com::sun::star::container::NoSuchElementException; + +using com::sun::star::uno::Reference; +using com::sun::star::uno::Exception; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::lang::IllegalArgumentException; +using com::sun::star::lang::IndexOutOfBoundsException; + +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::XFastPropertySet; +using com::sun::star::beans::XMultiPropertySet; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::Property; + +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::SQLException; + +namespace pq_sdbc_driver +{ + +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +User::User( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings ) + : ReflectionBase( + getStatics().refl.user.implName, + getStatics().refl.user.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.user.pProps ) +{} + +Reference< XPropertySet > User::createDataDescriptor( ) throw (RuntimeException) +{ + UserDescriptor * pUser = new UserDescriptor( m_refMutex, m_conn, m_pSettings ); + pUser->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pUser ); +} + + +Sequence User::getTypes() throw( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< com::sun::star::sdbcx::XUser> *) 0 ), + ReflectionBase::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> User::getImplementationId() throw( RuntimeException ) +{ + return getStatics().refl.user.implementationId; +} + +Any User::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = ReflectionBase::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< com::sun::star::sdbcx::XUser * > ( this ) ); + return ret; +} + + +void User::changePassword( + const ::rtl::OUString& oldPassword, const ::rtl::OUString& newPassword ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + rtl::OUStringBuffer buf(128); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER USER " ) ); + bufferQuoteIdentifier( buf, extractStringProperty( this, getStatics().NAME ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " PASSWORD " ) ); + bufferQuoteConstant( buf, newPassword, m_pSettings->encoding ); + Reference< XStatement > stmt = m_conn->createStatement(); + DisposeGuard guard( stmt ); + stmt->executeUpdate( buf.makeStringAndClear() ); +} + +sal_Int32 User::getPrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + sal_Int32 ret = 0xffffffff; + if( isLog( m_pSettings, LogLevel::INFO ) ) + { + Statics & st = getStatics(); + rtl::OUString user = extractStringProperty( this, st.NAME ); + + rtl::OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("User::getPrivileges[") ); + buf.append( extractStringProperty( this, st.NAME ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "] got called for " ) ); + buf.append( objName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "(type=" ) ); + buf.append( objType ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) ); + log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() ); + } + // all privileges + return ret; +} + +sal_Int32 User::getGrantablePrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + // all privileges + return 0xffffffff; +} + +void User::grantPrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + throw com::sun::star::sdbc::SQLException( + ASCII_STR( "pq_driver: privilege change not implemented yet" ), + *this, OUString(), 1, Any() ); +} + +void User::revokePrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) + throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + throw com::sun::star::sdbc::SQLException( + ASCII_STR( "pq_driver: privilege change not implemented yet" ), + *this, OUString(), 1, Any() ); +} + +//______________________________________________________________________________________ +UserDescriptor::UserDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings ) + : ReflectionBase( + getStatics().refl.userDescriptor.implName, + getStatics().refl.userDescriptor.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.userDescriptor.pProps ) +{} + +Reference< XPropertySet > UserDescriptor::createDataDescriptor( ) throw (RuntimeException) +{ + UserDescriptor * pUser = new UserDescriptor( m_refMutex, m_conn, m_pSettings ); + pUser->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pUser ); +} + + +} diff --git connectivity/source/drivers/postgresql/pq_xuser.hxx connectivity/source/drivers/postgresql/pq_xuser.hxx new file mode 100644 index 0000000..fc33174 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xuser.hxx @@ -0,0 +1,132 @@ +/************************************************************************* + * + * $RCSfile: pq_xuser.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:12 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_USER_HXX_ +#define HEADER_PQ_USER_HXX_ + +#include +#include + +#include +#include +#include + +#include "pq_xbase.hxx" + +namespace pq_sdbc_driver +{ + +class User : public ReflectionBase, + public com::sun::star::sdbcx::XUser +{ + +public: + User( const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); +public: + void refetch(); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XUser : XAuthorizable + // Methods + virtual sal_Int32 SAL_CALL getPrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getGrantablePrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL grantPrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL revokePrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL changePassword( const ::rtl::OUString& oldPassword, const ::rtl::OUString& newPassword ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + +}; + +class UserDescriptor : public ReflectionBase +{ +public: + UserDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); +}; + +} + + +#endif diff --git connectivity/source/drivers/postgresql/pq_xusers.cxx connectivity/source/drivers/postgresql/pq_xusers.cxx new file mode 100644 index 0000000..85da3e7 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xusers.cxx @@ -0,0 +1,256 @@ +/************************************************************************* + * + * $RCSfile: pq_xusers.cxx,v $ + * + * $Revision: 1.1.2.4 $ + * + * last change: $Author: jbu $ $Date: 2006/01/22 15:14:41 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include "pq_xusers.hxx" +#include "pq_xuser.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::beans::XPropertySet; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::container::NoSuchElementException; +using com::sun::star::lang::WrappedTargetException; + +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XDatabaseMetaData; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) +Users::Users( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ) + : Container( refMutex, origin, pSettings, getStatics().USER ) +{} + +Users::~Users() +{} + +void Users::refresh() + throw (::com::sun::star::uno::RuntimeException) +{ + try + { + osl::MutexGuard guard( m_refMutex->mutex ); + Statics & st = getStatics(); + + Reference< XStatement > stmt = m_origin->createStatement(); + + Reference< XResultSet > rs = + stmt->executeQuery( ASCII_STR( "SELECT usename FROM pg_shadow" ) ); + + Reference< XRow > xRow( rs , UNO_QUERY ); + + String2IntMap map; + + std::vector< Any, Allocator< Any> > vec; + sal_Int32 tableIndex = 0; + while( rs->next() ) + { + User * pUser = + new User( m_refMutex, m_origin, m_pSettings ); + Reference< com::sun::star::beans::XPropertySet > prop = pUser; + + OUString name = xRow->getString( 1); + pUser->setPropertyValue_NoBroadcast_public( + st.NAME , makeAny(xRow->getString( TABLE_INDEX_CATALOG+1) ) ); + + vec.push_back( makeAny(prop ) ); + map[ name ] = tableIndex; + tableIndex ++; + } + m_values = Sequence< com::sun::star::uno::Any > ( & vec[0] , vec.size() ); + m_name2index.swap( map ); + } + catch ( com::sun::star::sdbc::SQLException & e ) + { + throw RuntimeException( e.Message , e.Context ); + } + + fire( RefreshedBroadcaster( *this ) ); +} + + +void Users::appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + Statics &st = getStatics(); + + OUStringBuffer update( 128 ); + update.appendAscii( RTL_CONSTASCII_STRINGPARAM( "CREATE USER " ) ); + bufferQuoteIdentifier( update, extractStringProperty( descriptor, getStatics().NAME ) ); + update.appendAscii( RTL_CONSTASCII_STRINGPARAM( " PASSWORD " ) ); + bufferQuoteConstant( update, extractStringProperty( descriptor, getStatics().PASSWORD ), m_pSettings->encoding ); + + Reference< XStatement > stmt = m_origin->createStatement( ); + DisposeGuard disposeGuard( stmt ); + stmt->executeUpdate( update.makeStringAndClear() ); +} + +void Users::dropByName( const ::rtl::OUString& elementName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException) +{ + String2IntMap::const_iterator ii = m_name2index.find( elementName ); + if( ii == m_name2index.end() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "User " ); + buf.append( elementName ); + buf.appendAscii( " is unknown, so it can't be dropped" ); + throw com::sun::star::container::NoSuchElementException( + buf.makeStringAndClear(), *this ); + } + dropByIndex( ii->second ); +} + +void Users::dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException) +{ + + osl::MutexGuard guard( m_refMutex->mutex ); + if( index < 0 || index >= m_values.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "USERS: Index out of range (allowed 0 to " ); + buf.append( (sal_Int32) (m_values.getLength() -1) ); + buf.appendAscii( ", got " ); + buf.append( index ); + buf.appendAscii( ")" ); + throw com::sun::star::lang::IndexOutOfBoundsException( + buf.makeStringAndClear(), *this ); + } + + Reference< XPropertySet > set; + m_values[index] >>= set; + Statics &st = getStatics(); + OUString name; + set->getPropertyValue( getStatics().NAME ) >>= name; + + OUStringBuffer update( 128 ); + update.appendAscii( "DROP USER " ); + bufferQuoteIdentifier( update, name ); + + Reference< XStatement > stmt = m_origin->createStatement( ); + DisposeGuard disposeGuard( stmt ); + stmt->executeUpdate( update.makeStringAndClear() ); +} + + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Users::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new UserDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +Reference< com::sun::star::container::XNameAccess > Users::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ) +{ + Users *pUsers = new Users( refMutex, origin, pSettings ); + Reference< com::sun::star::container::XNameAccess > ret = pUsers; + pUsers->refresh(); + + return ret; +} + +void Users::disposing() +{ +} + +}; diff --git connectivity/source/drivers/postgresql/pq_xusers.hxx connectivity/source/drivers/postgresql/pq_xusers.hxx new file mode 100644 index 0000000..a70672d --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xusers.hxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * $RCSfile: pq_xusers.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/05/09 19:47:25 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef HEADER_PQ_USERS_HXX_ +#define HEADER_PQ_USERS_HXX_ + +#include "pq_xcontainer.hxx" + +namespace pq_sdbc_driver +{ + +class Users : public Container +{ + +public: // instances Tables 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ); + +protected: + Users( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ); + + virtual ~Users(); + +public: // XAppend + virtual void SAL_CALL appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +public: // XDrop + virtual void SAL_CALL dropByName( const ::rtl::OUString& elementName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // XRefreshable + virtual void SAL_CALL refresh( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); + +protected: + virtual void SAL_CALL disposing(); +}; + +} +#endif diff --git connectivity/source/drivers/postgresql/pq_xview.cxx connectivity/source/drivers/postgresql/pq_xview.cxx new file mode 100644 index 0000000..3377d97 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xview.cxx @@ -0,0 +1,285 @@ +/************************************************************************* + * + * $RCSfile: pq_xview.cxx,v $ + * + * $Revision: 1.1.2.5 $ + * + * last change: $Author: jbu $ $Date: 2007/01/07 13:50:38 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "pq_xview.hxx" +#include "pq_xviews.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; +using osl::Mutex; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::container::XNameAccess; +using com::sun::star::container::XIndexAccess; +using com::sun::star::container::ElementExistException; +using com::sun::star::container::NoSuchElementException; + +using com::sun::star::uno::Reference; +using com::sun::star::uno::Exception; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::lang::IllegalArgumentException; +using com::sun::star::lang::IndexOutOfBoundsException; + +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::XFastPropertySet; +using com::sun::star::beans::XMultiPropertySet; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::Property; + +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::SQLException; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +View::View( const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings) + : ReflectionBase( + getStatics().refl.view.implName, + getStatics().refl.view.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.view.pProps ) +{} + +Reference< XPropertySet > View::createDataDescriptor( ) throw (RuntimeException) +{ + ViewDescriptor * pView = new ViewDescriptor( + m_refMutex, m_conn, m_pSettings ); + pView->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pView ); +} + +void View::rename( const ::rtl::OUString& newName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + MutexGuard guard( m_refMutex->mutex ); + + Statics & st = getStatics(); + + ::rtl::OUString oldName = extractStringProperty(this,st.NAME ); + ::rtl::OUString schema = extractStringProperty(this,st.SCHEMA_NAME ); + ::rtl::OUString fullOldName = concatQualified( schema, oldName ); + + OUString newTableName; + OUString newSchemaName; + // OOo2.0 passes schema + dot + new-table-name while + // OO1.1.x passes new Name without schema + // in case name contains a dot, it is interpreted as schema.tablename + if( newName.indexOf( '.' ) >= 0 ) + { + splitConcatenatedIdentifier( newName, &newSchemaName, &newTableName ); + } + else + { + newTableName = newName; + newSchemaName = schema; + } + ::rtl::OUString fullNewName = concatQualified( newSchemaName, newTableName ); + + if( ! schema.equals( newSchemaName ) ) + { + try + { + OUStringBuffer buf(128); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); + bufferQuoteQualifiedIdentifier(buf, schema, oldName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("SET SCHEMA" ) ); + bufferQuoteIdentifier( buf, newSchemaName ); + Reference< XStatement > statement = m_conn->createStatement(); + statement->executeUpdate( buf.makeStringAndClear() ); + setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME, makeAny(newSchemaName) ); + disposeNoThrow( statement ); + schema = newSchemaName; + } + catch( com::sun::star::sdbc::SQLException &e ) + { + OUStringBuffer buf( e.Message ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "(NOTE: Only postgresql server >= V8.1 support changing a table's schema)" ) ); + e.Message = buf.makeStringAndClear(); + throw e; + } + + } + if( ! oldName.equals( newTableName ) ) + { + OUStringBuffer buf(128); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) ); + bufferQuoteQualifiedIdentifier( buf, schema, oldName ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("RENAME TO" ) ); + bufferQuoteIdentifier( buf, newTableName ); + Reference< XStatement > statement = m_conn->createStatement(); + statement->executeUpdate( buf.makeStringAndClear() ); + setPropertyValue_NoBroadcast_public( st.NAME, makeAny(newTableName) ); + } + + // inform the container of the name change ! + if( m_pSettings->views.is() ) + { + m_pSettings->pViewsImpl->rename( fullOldName, fullNewName ); + } +} + +Sequence View::getTypes() throw( RuntimeException ) +{ + static cppu::OTypeCollection *pCollection; + if( ! pCollection ) + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( (Reference< com::sun::star::sdbcx::XRename> *) 0 ), + ReflectionBase::getTypes()); + pCollection = &collection; + } + } + return pCollection->getTypes(); +} + +Sequence< sal_Int8> View::getImplementationId() throw( RuntimeException ) +{ + return getStatics().refl.view.implementationId; +} + +Any View::queryInterface( const Type & reqType ) throw (RuntimeException) +{ + Any ret; + + ret = ReflectionBase::queryInterface( reqType ); + if( ! ret.hasValue() ) + ret = ::cppu::queryInterface( + reqType, + static_cast< com::sun::star::sdbcx::XRename * > ( this ) + ); + return ret; +} + +::rtl::OUString View::getName( ) throw (::com::sun::star::uno::RuntimeException) +{ + Statics & st = getStatics(); + return concatQualified( + extractStringProperty( this, st.SCHEMA_NAME ), + extractStringProperty( this, st.NAME ) ); +} + +void View::setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException) +{ + rename( aName ); +} + +//____________________________________________________________________________________________ + +ViewDescriptor::ViewDescriptor( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings) + : ReflectionBase( + getStatics().refl.viewDescriptor.implName, + getStatics().refl.viewDescriptor.serviceNames, + refMutex, + connection, + pSettings, + * getStatics().refl.viewDescriptor.pProps ) +{} + +Reference< XPropertySet > ViewDescriptor::createDataDescriptor( ) throw (RuntimeException) +{ + ViewDescriptor * pView = new ViewDescriptor( + m_refMutex, m_conn, m_pSettings ); + pView->copyValuesFrom( this ); + + return Reference< XPropertySet > ( pView ); +} + + +} diff --git connectivity/source/drivers/postgresql/pq_xview.hxx connectivity/source/drivers/postgresql/pq_xview.hxx new file mode 100644 index 0000000..77d40d1 --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xview.hxx @@ -0,0 +1,133 @@ +/************************************************************************* + * + * $RCSfile: pq_xview.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: jbu $ $Date: 2004/06/10 15:27:13 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef PQ_XVIEW_HXX +#define PQ_XVIEW_HXX + +#include +#include + +#include +#include +#include +#include + +#include "pq_xbase.hxx" + +namespace pq_sdbc_driver +{ +class Views; +class View : public ReflectionBase, + public com::sun::star::sdbcx::XRename +{ +public: + View( const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); +public: + void refetch(); + +public: // XInterface + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + virtual com::sun::star::uno::Any SAL_CALL queryInterface( + const com::sun::star::uno::Type & reqType ) + throw (com::sun::star::uno::RuntimeException); + +public: // XTypeProvider, first implemented by OPropertySetHelper + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL getTypes() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< sal_Int8> SAL_CALL getImplementationId() + throw( com::sun::star::uno::RuntimeException ); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XRename + virtual void SAL_CALL rename( const ::rtl::OUString& newName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +public: // XNamed + virtual ::rtl::OUString SAL_CALL getName( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + +}; + + +class ViewDescriptor : public ReflectionBase +{ +public: + ViewDescriptor( const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & connection, + ConnectionSettings *pSettings); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + createDataDescriptor( ) throw (::com::sun::star::uno::RuntimeException); +}; + +} + + +#endif diff --git connectivity/source/drivers/postgresql/pq_xviews.cxx connectivity/source/drivers/postgresql/pq_xviews.cxx new file mode 100644 index 0000000..df6c13a --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xviews.cxx @@ -0,0 +1,304 @@ +/************************************************************************* + * + * $RCSfile: pq_xviews.cxx,v $ + * + * $Revision: 1.1.2.4 $ + * + * last change: $Author: jbu $ $Date: 2006/05/01 19:19:09 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include "pq_xviews.hxx" +#include "pq_xview.hxx" +#include "pq_xtables.hxx" +#include "pq_statics.hxx" +#include "pq_tools.hxx" + +using osl::MutexGuard; + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::beans::XPropertySet; + +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; + +using com::sun::star::container::NoSuchElementException; +using com::sun::star::lang::WrappedTargetException; + +using com::sun::star::sdbc::XRow; +using com::sun::star::sdbc::XCloseable; +using com::sun::star::sdbc::XStatement; +using com::sun::star::sdbc::XResultSet; +using com::sun::star::sdbc::XParameters; +using com::sun::star::sdbc::XPreparedStatement; +using com::sun::star::sdbc::XDatabaseMetaData; + +// using com::sun::star::sdbcx::Privilege; + +namespace pq_sdbc_driver +{ +#define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) +Views::Views( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings ) + : Container( refMutex, origin, pSettings, getStatics().VIEW ) +{} + +Views::~Views() +{} + +void Views::refresh() + throw (::com::sun::star::uno::RuntimeException) +{ + try + { + osl::MutexGuard guard( m_refMutex->mutex ); + Statics & st = getStatics(); + + Reference< XStatement > stmt = m_origin->createStatement(); + + Reference< XResultSet > rs = stmt->executeQuery( + ASCII_STR( "SELECT " + "DISTINCT ON( pg_namespace.nspname, relname) " // needed because of duplicates + "pg_namespace.nspname," // 1 + "relname," // 2 + "pg_get_viewdef(ev_class) " // 3 + "FROM pg_namespace, pg_class, pg_rewrite " + "WHERE pg_namespace.oid = relnamespace " + "AND pg_class.oid = ev_class " + "AND relkind='v'" ) ); + + Reference< XRow > xRow( rs , UNO_QUERY ); + + std::vector< Any, Allocator< Any> > vec; + String2IntMap map; + sal_Int32 viewIndex = 0; + + while( rs->next() ) + { + rtl::OUString table, schema, command; + schema = xRow->getString( 1 ); + table = xRow->getString( 2 ); + command = xRow->getString( 3 ); + + View *pView = new View (m_refMutex, m_origin, m_pSettings ); + Reference< com::sun::star::beans::XPropertySet > prop = pView; + + pView->setPropertyValue_NoBroadcast_public(st.NAME , makeAny(table) ); + pView->setPropertyValue_NoBroadcast_public(st.SCHEMA_NAME, makeAny(schema) ); + pView->setPropertyValue_NoBroadcast_public(st.COMMAND, makeAny(command) ); + vec.push_back( makeAny( prop ) ); + + OUStringBuffer buf( table.getLength() + schema.getLength() + 1); + buf.append( schema ).appendAscii( "." ).append( table ); + map[ buf.makeStringAndClear() ] = viewIndex; + viewIndex ++; + + } + m_values = Sequence< com::sun::star::uno::Any > ( &vec[0], vec.size() ); + m_name2index.swap( map ); + } + catch ( com::sun::star::sdbc::SQLException & e ) + { + throw RuntimeException( e.Message , e.Context ); + } + fire( RefreshedBroadcaster( *this ) ); +} + + +void Views::appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException) +{ + osl::MutexGuard guard( m_refMutex->mutex ); + + Statics &st = getStatics(); + OUString name,schema,command; + descriptor->getPropertyValue( st.SCHEMA_NAME ) >>= schema; + descriptor->getPropertyValue( st.NAME ) >>= name; + descriptor->getPropertyValue( st.COMMAND ) >>= command; + + Reference< XStatement > stmt = m_origin->createStatement(); + + OUStringBuffer buf( 128 ); + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "CREATE VIEW " ) ); + bufferQuoteQualifiedIdentifier( buf, schema, name ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " AS " ) ); + buf.append( command ); + + stmt->executeUpdate( buf.makeStringAndClear() ); + + disposeNoThrow( stmt ); + refresh(); + if( m_pSettings->tables.is() ) + { + m_pSettings->pTablesImpl->refresh(); + } + // increase the vector +// sal_Int32 index = m_values.getLength(); +// m_values.realloc( index + 1 ); + +// View * pView = +// new View( m_refMutex, m_origin, m_pSettings, false /*modifiable*/ ); +// Reference< com::sun::star::beans::XPropertySet > prop = pTable; +// copyProperties( pTable, descriptor ); +// m_values[index] = makeAny( prop ); +// OUStringBuffer buf( name.getLength() + 1 + schema.getLength() ); +// buf.append( schema ).appendAscii( "." ).append( name ); +// m_name2index[ buf.makeStringAndClear() ] = index; +} + +void Views::dropByName( const ::rtl::OUString& elementName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException) +{ + String2IntMap::const_iterator ii = m_name2index.find( elementName ); + if( ii == m_name2index.end() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "View " ); + buf.append( elementName ); + buf.appendAscii( " is unknown, so it can't be dropped" ); + throw com::sun::star::container::NoSuchElementException( + buf.makeStringAndClear(), *this ); + } + dropByIndex( ii->second ); +} + +void Views::dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException) +{ +// throw SQLException( +// ASCII_STR( "view deletion not supported" ), *this, OUString(), 1, Any() ); + osl::MutexGuard guard( m_refMutex->mutex ); + if( index < 0 || index >= m_values.getLength() ) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( "VIEWS: Index out of range (allowed 0 to " ); + buf.append( (sal_Int32) (m_values.getLength() -1) ); + buf.appendAscii( ", got " ); + buf.append( index ); + buf.appendAscii( ")" ); + throw com::sun::star::lang::IndexOutOfBoundsException( + buf.makeStringAndClear(), *this ); + } + + Reference< XPropertySet > set; + m_values[index] >>= set; + Statics &st = getStatics(); + OUString name,schema; + set->getPropertyValue( st.SCHEMA_NAME ) >>= schema; + set->getPropertyValue( st.NAME ) >>= name; + + OUStringBuffer update( 128 ); + update.appendAscii( "DROP VIEW \"" ).append( schema ).appendAscii( "\".\"" ); + update.append( name ).appendAscii( "\"" ); + + Reference< XStatement > stmt = m_origin->createStatement( ); + + stmt->executeUpdate( update.makeStringAndClear() ); +} + + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Views::createDataDescriptor() + throw (::com::sun::star::uno::RuntimeException) +{ + return new ViewDescriptor( m_refMutex, m_origin, m_pSettings ); +} + +Reference< com::sun::star::container::XNameAccess > Views::create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + Views **ppViews) +{ + *ppViews = new Views( refMutex, origin, pSettings ); + Reference< com::sun::star::container::XNameAccess > ret = *ppViews; + (*ppViews)->refresh(); + + return ret; +} + +void Views::disposing() +{ + Container::disposing(); +} + + + +}; diff --git connectivity/source/drivers/postgresql/pq_xviews.hxx connectivity/source/drivers/postgresql/pq_xviews.hxx new file mode 100644 index 0000000..b1d7b9f --- /dev/null +++ connectivity/source/drivers/postgresql/pq_xviews.hxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * $RCSfile: pq_xviews.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: jbu $ $Date: 2004/05/09 19:47:26 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Joerg Budischewski + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Joerg Budischewski + * + * + ************************************************************************/ + +#ifndef _PQ_VIEWS_HXX_ +#define _PQ_VIEWS_HXX_ + +#include "pq_xcontainer.hxx" + +namespace pq_sdbc_driver +{ + +class Views : public Container +{ + +public: // instances Views 'exception safe' + static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > create( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings, + Views **ppViews ); + +protected: + Views( + const ::rtl::Reference< RefCountedMutex > & refMutex, + const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin, + ConnectionSettings *pSettings); + + virtual ~Views(); + +public: // XAppend + virtual void SAL_CALL appendByDescriptor( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + +public: // XDrop + virtual void SAL_CALL dropByName( const ::rtl::OUString& elementName ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dropByIndex( sal_Int32 index ) + throw (::com::sun::star::sdbc::SQLException, + ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + +public: // XRefreshable + virtual void SAL_CALL refresh( ) throw (::com::sun::star::uno::RuntimeException); + +public: // XDataDescriptorFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) + throw (::com::sun::star::uno::RuntimeException); + +protected: + virtual void SAL_CALL disposing(); + + +}; +} +#endif -- 1.7.0.1