summaryrefslogtreecommitdiff
path: root/connectivity
diff options
context:
space:
mode:
authorDamjan Jovanovic <damjan@apache.org>2017-08-20 19:16:28 +0000
committerDamjan Jovanovic <damjan@apache.org>2017-08-20 19:16:28 +0000
commit330392f87e90e4345273d42425b3ffc735281a7c (patch)
treefd3296aa82cf4ba3bcc659cd3776c1df3083bdb0 /connectivity
parent6dd83d1c6c5c580d14ca3d0458be4020603ba118 (diff)
#i127350# - Table design: can't change length of Postgresql char types
Add the initial version of a new SDBC driver, for the PostgreSQL database. Also its build changes: since it needs Apache Commons Lang version 3, get configure.ac to check for that, and get that to always build, just like our driver does. Patch by: me
Notes
Notes: prefer: e28033fdfad9750ebe96885b9514adee629acf88
Diffstat (limited to 'connectivity')
-rw-r--r--connectivity/java/sdbc_postgresql/build.xml249
-rw-r--r--connectivity/java/sdbc_postgresql/makefile.mk50
-rw-r--r--connectivity/java/sdbc_postgresql/postgresql.component30
-rw-r--r--connectivity/java/sdbc_postgresql/sdbc_postgresql.xcu71
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlCatalog.java90
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlConnection.java198
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlDatabaseMetadata.java752
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlDriver.java199
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlPreparedStatement.java348
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlResultSet.java495
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlResultSetMetaData.java127
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlStatement.java188
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlTable.java125
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlTables.java151
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/CompHelper.java74
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OArrayEnumeration.java55
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OEnumerationByIndex.java118
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OEnumerationByName.java116
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/PropertySet.java160
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/PropertySetAdapter.java411
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/ISQLStatementHelper.java28
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OCatalog.java169
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OColumn.java279
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OColumnContainer.java123
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OContainer.java461
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/ODescriptor.java76
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndex.java121
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexColumn.java96
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexColumnContainer.java121
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexContainer.java208
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKey.java150
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyColumn.java101
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyColumnContainer.java115
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyContainer.java277
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OTable.java187
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OfficeResourceBundle.java130
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/Resources.java66
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/SharedResources.java213
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/SqlTableHelper.java261
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxColumnDescriptor.java194
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxColumnDescriptorContainer.java36
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxDescriptorContainer.java59
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexColumnDescriptor.java58
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexColumnDescriptorContainer.java35
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexDescriptor.java94
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexDescriptorContainer.java44
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyColumnDescriptor.java58
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyColumnDescriptorContainer.java35
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyDescriptor.java113
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyDescriptorContainer.java44
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxTableDescriptor.java109
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ComposeRule.java31
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DBTypeConversion.java426
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DatabaseMetaDataResultSet.java489
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DbTools.java679
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameAccessAdapter.java91
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameContainerAdapter.java77
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ORowSetValue.java1154
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/Osl.java36
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/PropertyIds.java95
-rw-r--r--connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/StandardSQLState.java58
-rw-r--r--connectivity/prj/build.lst3
-rw-r--r--connectivity/prj/d.lst2
-rw-r--r--connectivity/target.pmk3
64 files changed, 11210 insertions, 2 deletions
diff --git a/connectivity/java/sdbc_postgresql/build.xml b/connectivity/java/sdbc_postgresql/build.xml
new file mode 100644
index 000000000000..42f8b5d33970
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/build.xml
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ ***********************************************************-->
+
+
+<project name="sdbc_postgresql" default="main" basedir=".">
+
+ <!-- ================================================================= -->
+ <!-- settings -->
+ <!-- ================================================================= -->
+
+ <!-- global properties -->
+ <property file="../../../ant.properties"/>
+ <!-- version info -->
+ <property file="../../../solenv/inc/minor.mk"/>
+
+ <!-- name of this sub target used in recursive builds -->
+ <property name="target" value="sdbc_postgresql"/>
+
+ <!-- name of jar file created, without .jar extension -->
+ <property name="jarname" value="sdbc_postgresql"/>
+
+ <!-- relative path to project directory -->
+ <property name="prj" value="../.."/>
+
+ <!-- build output directory -->
+ <!-- FIXME: there are also extremely rare/obsolete dbcs/bndchk/truetime/hbtoolkit cases in main/solenv/inc/settings.mk -->
+ <condition property="out" value="${prj}/${OUTPATH}.cap">
+ <isset property="${profile}"/>
+ </condition>
+ <condition property="out" value="${prj}/${OUTPATH}.pro">
+ <isset property="${PRODUCT}"/>
+ </condition>
+ <property name="out" value="${prj}/${OUTPATH}"/>
+
+ <!-- build directories -->
+ <property name="build.dir" value="${out}"/>
+ <property name="build.class" value="${build.dir}/class/${target}"/>
+ <property name="build.misc" value="${build.dir}/misc/${target}"/>
+
+ <!-- start of java source code package structure -->
+ <property name="java.dir" value="src"/>
+
+ <!-- define how to handle CLASSPATH environment -->
+ <property name="build.sysclasspath" value="ignore"/>
+
+ <!-- classpath settings for compile and javadoc tasks -->
+ <condition property="jar-class-path" value="${COMMONS_LANG_JAR}" else="commons-lang3-3.3.jar">
+ <equals arg1="${SYSTEM_APACHE_COMMONS}" arg2="YES"/>
+ </condition>
+ <condition property="commons-lang-jar" value="${COMMONS_LANG_JAR}" else="${OUTDIR}/bin/commons-lang3-3.3.jar">
+ <equals arg1="${SYSTEM_APACHE_COMMONS}" arg2="YES"/>
+ </condition>
+ <path id="classpath">
+ <pathelement location="${OUTDIR}/bin/juh.jar"/>
+ <pathelement location="${OUTDIR}/bin/jurt.jar"/>
+ <pathelement location="${OUTDIR}/bin/ridl.jar"/>
+ <pathelement location="${OUTDIR}/bin/unoil.jar"/>
+ <!-- 3rd party libs -->
+ <pathelement location="${commons-lang-jar}"/>
+ </path>
+
+ <!-- name to display in documentation -->
+ <property name="docname" value="sdbc_postgresql"/>
+
+ <!-- set "modern" java compiler -->
+ <property name="build.compiler" value="modern"/>
+
+ <!-- set wether we want to compile with debug information -->
+ <property name="debug" value="on"/>
+
+ <!-- set wether we want to compile with optimisation -->
+ <property name="optimize" value="off"/>
+
+ <!-- set wether we want to compile with or without deprecation -->
+ <property name="deprecation" value="on"/>
+
+ <target name="info">
+ <echo message="--------------------"/>
+ <echo message="${target}"/>
+ <echo message="--------------------"/>
+ </target>
+
+ <!-- ================================================================= -->
+ <!-- custom targets -->
+ <!-- ================================================================= -->
+
+ <!-- the main target, called in recursive builds -->
+ <target name="main" depends="info,prepare,compile,jar,javadoc,zipdoc"/>
+
+ <!-- prepare output directories -->
+ <target name="prepare">
+ <mkdir dir="${build.dir}"/>
+ <mkdir dir="${build.dir}/doc/${target}"/>
+ <mkdir dir="${build.class}"/>
+ <mkdir dir="${build.misc}"/>
+ </target>
+
+
+ <target name="res" depends="prepare">
+ <copy todir="${build.class}">
+ <fileset dir="${java.dir}">
+ <include name="**/*.properties"/>
+ <include name="**/*.css"/>
+ <include name="**/*.dtd"/>
+ <include name="**/*.form"/>
+ <include name="**/*.gif "/>
+ <include name="**/*.htm"/>
+ <include name="**/*.html"/>
+ <include name="**/*.js"/>
+ <include name="**/*.mod"/>
+ <include name="**/*.sql"/>
+ <include name="**/*.xml"/>
+ <include name="**/*.xsl"/>
+ <include name="**/*.map"/>
+
+ </fileset>
+ </copy>
+ </target>
+
+
+ <target name="compile" depends="prepare,res">
+ <javac destdir="${build.class}"
+ debug="${debug}"
+ debuglevel="lines,vars,source"
+ deprecation="${deprecation}"
+ optimize="${optimize}"
+ classpathref="classpath">
+ <src path="${java.dir}"/>
+ <include name="**/*.java"/>
+ </javac>
+ </target>
+
+ <!-- check if javadoc is up to date -->
+ <target name="javadoc_check" depends="prepare" if="build.dir">
+ <uptodate property="javadocBuild.notRequired" value="true"
+ targetfile="${build.dir}/doc/${target}/${target}_javadoc.zip">
+ <srcfiles dir="${java.dir}" includes="**/*.java"/>
+ </uptodate>
+ </target>
+
+ <!-- generate java documentation -->
+ <target name="javadoc" depends="prepare,javadoc_check,compile"
+ unless="javadocBuild.notRequired"
+ if="build.dir">
+
+ <javadoc destdir="${build.dir}/doc/${target}/javadoc"
+ verbose="false"
+ author="false"
+ nodeprecated="true"
+ nodeprecatedlist="true"
+ use="true"
+ Doctitle="${docname}"
+ windowtitle="${docname}"
+ classpathref="classpath">
+
+ <packageset dir="${java.dir}" defaultexcludes="yes">
+ <include name="com/**"/>
+ <include name="org/**"/>
+ </packageset>
+
+ <link offline="true" href="http://java.sun.com/j2se/1.4.2/docs/api"
+ packagelistLoc="${common.doc}/jdk1.4.2"/>
+ <link offline="true"
+ href="http://java.sun.com/products/servlet/2.3/javadoc"
+ packagelistLoc="${common.doc}/servlet2.3"/>
+ <link offline="true"
+ href="http://logging.apache.org/log4j/docs/api"
+ packagelistLoc="${common.doc}/log4j-1.2.8"/>
+ <link offline="true"
+ href="http://java.sun.com/products/javabeans/glasgow/javadocs"
+ packagelistLoc="${common.doc}/jaf-1.0.2"/>
+ <link offline="true"
+ href="http://java.sun.com/products/javamail/javadocs"
+ packagelistLoc="${common.doc}/javamail-1.3.1"/>
+ <link offline="true"
+ href="http://ws.apache.org/soap/docs"
+ packagelistLoc="${common.doc}/soap-2.3.1"/>
+
+ <bottom>&lt;i&gt;Copyright &amp;#169; 2004 Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, CA 94303 USA&lt;/i&gt;</bottom>
+ <header>${docname}</header>
+
+ </javadoc>
+ </target>
+
+ <!-- zip documentation and store in build/doc/${target} -->
+ <target name="zipdoc" depends="javadoc" if="build.dir" unless="javadocBuild.notRequired">
+ <zip zipfile="${build.dir}/doc/${target}/${target}_javadoc.zip"
+ basedir="${build.dir}/doc/${target}/javadoc"
+ update="true"/>
+ </target>
+
+ <!-- clean up -->
+ <target name="clean" depends="prepare">
+ <delete dir="${build.class}" includeEmptyDirs="true"/>
+ <delete dir="${build.dir}/doc/${target}" includeEmptyDirs="true"/>
+ </target>
+
+ <!-- create jar file -->
+ <target name="jar" depends="prepare,compile" if="build.class">
+ <jar jarfile="${build.class}/${jarname}.jar"
+ basedir="${build.class}">
+ <manifest>
+ <attribute name="Class-Path" value="${jar-class-path} juh.jar jurt.jar ridl.jar unoil.jar"/>
+ <attribute name="Solar-Version" value="${RSCREVISION}"/>
+ <attribute name="RegistrationClassName" value="com.sun.star.sdbcx.comp.postgresql.PostgresqlDriver"/>
+ <attribute name="Sealed" value="true"/>
+ <attribute name="UNO-Type-Path" value=""/>
+ </manifest>
+ <include name="**/*.class"/>
+ <include name="**/*.properties"/>
+ <include name="**/*.css"/>
+ <include name="**/*.dtd"/>
+ <include name="**/*.form"/>
+ <include name="**/*.gif "/>
+ <include name="**/*.htm"/>
+ <include name="**/*.html"/>
+ <include name="**/*.js"/>
+ <include name="**/*.mod"/>
+ <include name="**/*.sql"/>
+ <include name="**/*.xml"/>
+ <include name="**/*.xsl"/>
+ <include name="**/*.map"/>
+ </jar>
+ </target>
+
+ <target name="test" depends="prepare">
+ </target>
+
+</project>
+
diff --git a/connectivity/java/sdbc_postgresql/makefile.mk b/connectivity/java/sdbc_postgresql/makefile.mk
new file mode 100644
index 000000000000..bab2fc72a123
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/makefile.mk
@@ -0,0 +1,50 @@
+#**************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#**************************************************************
+
+
+
+PRJ=..$/..
+PRJNAME=connectivity
+TARGET=sdbc_postgresql
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : $(PRJ)$/makefile.pmk
+.INCLUDE : $(PRJ)$/version.mk
+
+.IF defined(debug) || defined(DEBUG)
+ANTDEBUG=true
+.ELSE
+ANTDEBUG=off
+.ENDIF
+
+ANT_FLAGS+=-Dantdebug=$(ANTDEBUG)
+
+# --- Targets ------------------------------------------------------
+.INCLUDE : $(PRJ)$/target.pmk
+
+ALLTAR: ANTBUILD $(MISC)/postgresql.component
+
+$(MISC)/postgresql.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ postgresql.component
+ $(XSLTPROC) --nonet --stringparam uri '$(COMPONENTPREFIX_URE_JAVA)sdbc_postgresql.jar' \
+ -o $@ $(SOLARENV)/bin/createcomponent.xslt postgresql.component
+
diff --git a/connectivity/java/sdbc_postgresql/postgresql.component b/connectivity/java/sdbc_postgresql/postgresql.component
new file mode 100644
index 000000000000..d1f0ce6f85b0
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/postgresql.component
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ ***********************************************************-->
+
+
+
+<component loader="com.sun.star.loader.Java2"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.sdbcx.comp.postgresql.PostgresqlDriver">
+ <service name="com.sun.star.sdbc.Driver"/>
+ </implementation>
+</component>
diff --git a/connectivity/java/sdbc_postgresql/sdbc_postgresql.xcu b/connectivity/java/sdbc_postgresql/sdbc_postgresql.xcu
new file mode 100644
index 000000000000..38db83c28bb8
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/sdbc_postgresql.xcu
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ ***********************************************************-->
+
+
+<oor:component-data oor:name="Drivers" oor:package="org.openoffice.Office.DataAccess" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <node oor:name="Installed">
+ <node oor:name="sdbc:postgresql:jdbc:*" oor:op="replace">
+ <prop oor:name="Driver">
+ <value>com.sun.star.sdbcx.comp.postgresql.PostgresqlDriver</value>
+ </prop>
+ <prop oor:name="DriverTypeDisplayName" oor:type="xs:string">
+ <value xml:lang="en-US">PostgreSQL</value>
+ </prop>
+ <node oor:name="Properties">
+ <node oor:name="JavaDriverClass" oor:op="replace">
+ <prop oor:name="Value" oor:type="xs:string">
+ <value>org.postgresql.Driver</value>
+ </prop>
+ </node>
+ </node>
+ <node oor:name="Features">
+ </node>
+ <node oor:name="MetaData">
+ <node oor:name="SupportsBrowsing" oor:op="replace">
+ <prop oor:name="Value" oor:type="xs:boolean">
+ <value>true</value>
+ </prop>
+ </node>
+ <node oor:name="SupportsTableCreation" oor:op="replace">
+ <prop oor:name="Value" oor:type="xs:boolean">
+ <value>true</value>
+ </prop>
+ </node>
+ <node oor:name="UseJava" oor:op="replace">
+ <prop oor:name="Value" oor:type="xs:boolean">
+ <value>true</value>
+ </prop>
+ </node>
+ <node oor:name="Authentication" oor:op="replace">
+ <prop oor:name="Value" oor:type="xs:string">
+ <value>UserPassword</value>
+ </prop>
+ </node>
+ <node oor:name="SupportsColumnDescription" oor:op="replace">
+ <prop oor:name="Value" oor:type="xs:boolean">
+ <value>true</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlCatalog.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlCatalog.java
new file mode 100644
index 000000000000..638b8f31c947
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlCatalog.java
@@ -0,0 +1,90 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OCatalog;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OContainer;
+import com.sun.star.uno.Any;
+import com.sun.star.uno.UnoRuntime;
+
+public class PostgresqlCatalog extends OCatalog {
+ public PostgresqlCatalog(PostgresqlConnection connection) throws SQLException {
+ super(connection.getMetaData());
+ }
+
+ @Override
+ public OContainer refreshTables() {
+ XResultSet results = null;
+ try {
+ // Using { "VIEW", "TABLE", "%" } shows INFORMATION_SCHEMA and others, but it also shows indexes :-(
+ results = metadata.getTables(Any.VOID, "%", "%", new String[] { "VIEW", "TABLE" });
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ List<String> names = new ArrayList<>();
+ while (results.next()) {
+ String name = buildName(row);
+ System.out.println("Table " + name);
+ names.add(name);
+ }
+ return new PostgresqlTables(lock, metadata, this, names);
+ } catch (SQLException sqlException) {
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+ return null;
+ }
+
+ @Override
+ public OContainer refreshViews() {
+ XResultSet results = null;
+ try {
+ results = metadata.getTables(Any.VOID, "%", "%", new String[] { "VIEW" });
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ List<String> names = new ArrayList<>();
+ while (results.next()) {
+ String name = buildName(row);
+ names.add(name);
+ }
+ return new PostgresqlTables(lock, metadata, this, names);
+ } catch (SQLException sqlException) {
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+ return null;
+ }
+
+ @Override
+ public OContainer refreshGroups() {
+ return null;
+ }
+
+ @Override
+ public OContainer refreshUsers() {
+ return null;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlConnection.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlConnection.java
new file mode 100644
index 000000000000..8e1d554d7805
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlConnection.java
@@ -0,0 +1,198 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.sun.star.container.XNameAccess;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XEventListener;
+import com.sun.star.lib.uno.helper.ComponentBase;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbc.XDatabaseMetaData;
+import com.sun.star.sdbc.XPreparedStatement;
+import com.sun.star.sdbc.XStatement;
+import com.sun.star.sdbc.XWarningsSupplier;
+import com.sun.star.uno.UnoRuntime;
+
+public class PostgresqlConnection extends ComponentBase implements XConnection, XWarningsSupplier, XEventListener {
+ private XConnection impl;
+ private XComponent implComponent;
+ private XWarningsSupplier implWarningsSupplier;
+ private String url;
+ private AtomicBoolean isDisposed = new AtomicBoolean(false);
+ private HashSet<XComponent> statements = new HashSet<>();
+
+ public PostgresqlConnection(XConnection impl, String url) {
+ this.impl = impl;
+ implComponent = UnoRuntime.queryInterface(XComponent.class, impl);
+ implWarningsSupplier = UnoRuntime.queryInterface(XWarningsSupplier.class, impl);
+ this.url = url;
+ }
+
+ // XComponent:
+
+ @Override
+ protected synchronized void postDisposing() {
+ isDisposed.set(true);
+ implComponent.dispose();
+ for (XComponent pgStatement : statements) {
+ try {
+ pgStatement.dispose();
+ } catch (DisposedException disposedException) {
+ }
+ }
+ };
+
+ private void checkDisposed() throws DisposedException {
+ if (isDisposed.get()) {
+ throw new DisposedException();
+ }
+ }
+
+ // XEventListener:
+
+ public synchronized void disposing(EventObject source) {
+ statements.remove(source.Source);
+ }
+
+ // XWarningsSupplier:
+
+ public void clearWarnings() throws SQLException {
+ checkDisposed();
+ implWarningsSupplier.clearWarnings();
+ }
+
+ public Object getWarnings() throws SQLException {
+ checkDisposed();
+ return implWarningsSupplier.getWarnings();
+ }
+
+ // XConnection:
+
+ public void close() throws SQLException {
+ dispose();
+ }
+
+ public void commit() throws SQLException {
+ checkDisposed();
+ impl.commit();
+ }
+
+ public synchronized XStatement createStatement() throws SQLException {
+ checkDisposed();
+ PostgresqlStatement pgStatement = new PostgresqlStatement(impl.createStatement(), this);
+ statements.add(pgStatement);
+ pgStatement.addEventListener(this);
+ return pgStatement;
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ checkDisposed();
+ return impl.getAutoCommit();
+ }
+
+ public String getCatalog() throws SQLException {
+ checkDisposed();
+ return impl.getCatalog();
+ }
+
+ public XDatabaseMetaData getMetaData() throws SQLException {
+ checkDisposed();
+ return new PostgresqlDatabaseMetadata(impl.getMetaData(), this, url);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ checkDisposed();
+ return impl.getTransactionIsolation();
+ }
+
+ public XNameAccess getTypeMap() throws SQLException {
+ checkDisposed();
+ return impl.getTypeMap();
+ }
+
+ public boolean isClosed() throws SQLException {
+ checkDisposed();
+ return impl.isClosed();
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ checkDisposed();
+ return impl.isReadOnly();
+ }
+
+ public String nativeSQL(String arg0) throws SQLException {
+ checkDisposed();
+ return impl.nativeSQL(arg0);
+ }
+
+ public synchronized XPreparedStatement prepareCall(String arg0) throws SQLException {
+ checkDisposed();
+ PostgresqlPreparedStatement pgStatement = new PostgresqlPreparedStatement(impl.prepareCall(arg0), this);
+ statements.add(pgStatement);
+ pgStatement.addEventListener(this);
+ return pgStatement;
+ }
+
+ public synchronized XPreparedStatement prepareStatement(String arg0) throws SQLException {
+ checkDisposed();
+ PostgresqlPreparedStatement pgStatement = new PostgresqlPreparedStatement(impl.prepareStatement(arg0), this);
+ statements.add(pgStatement);
+ pgStatement.addEventListener(this);
+ return pgStatement;
+ }
+
+ public void rollback() throws SQLException {
+ checkDisposed();
+ impl.rollback();
+ }
+
+ public void setAutoCommit(boolean arg0) throws SQLException {
+ checkDisposed();
+ impl.setAutoCommit(arg0);
+ }
+
+ public void setCatalog(String arg0) throws SQLException {
+ checkDisposed();
+ impl.setCatalog(arg0);
+ }
+
+ public void setReadOnly(boolean arg0) throws SQLException {
+ checkDisposed();
+ impl.setReadOnly(arg0);
+ }
+
+ public void setTransactionIsolation(int arg0) throws SQLException {
+ checkDisposed();
+ impl.setTransactionIsolation(arg0);
+ }
+
+ public void setTypeMap(XNameAccess arg0) throws SQLException {
+ checkDisposed();
+ impl.setTypeMap(arg0);
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlDatabaseMetadata.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlDatabaseMetadata.java
new file mode 100644
index 000000000000..3e0b24064362
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlDatabaseMetadata.java
@@ -0,0 +1,752 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import java.util.ArrayList;
+
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.sdbc.DataType;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbc.XDatabaseMetaData;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbcx.comp.postgresql.util.DatabaseMetaDataResultSet;
+import com.sun.star.sdbcx.comp.postgresql.util.ORowSetValue;
+import com.sun.star.uno.UnoRuntime;
+
+public class PostgresqlDatabaseMetadata extends WeakBase implements XDatabaseMetaData {
+ private XDatabaseMetaData impl;
+ private XConnection connection;
+ private String url;
+
+ public PostgresqlDatabaseMetadata(XDatabaseMetaData impl, XConnection connection, String url) {
+ this.impl = impl;
+ this.connection = connection;
+ this.url = url;
+ }
+
+ public boolean allProceduresAreCallable() throws SQLException {
+ return impl.allProceduresAreCallable();
+ }
+
+ public boolean allTablesAreSelectable() throws SQLException {
+ return impl.allTablesAreSelectable();
+ }
+
+ public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+ return impl.dataDefinitionCausesTransactionCommit();
+ }
+
+ public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+ return impl.dataDefinitionIgnoredInTransactions();
+ }
+
+ public boolean deletesAreDetected(int arg0) throws SQLException {
+ return impl.deletesAreDetected(arg0);
+ }
+
+ public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+ return impl.doesMaxRowSizeIncludeBlobs();
+ }
+
+ public XResultSet getBestRowIdentifier(Object arg0, String arg1, String arg2, int arg3, boolean arg4) throws SQLException {
+ return new PostgresqlResultSet(impl.getBestRowIdentifier(arg0, arg1, arg2, arg3, arg4), null);
+ }
+
+ public String getCatalogSeparator() throws SQLException {
+ return impl.getCatalogSeparator();
+ }
+
+ public String getCatalogTerm() throws SQLException {
+ return impl.getCatalogTerm();
+ }
+
+ public XResultSet getCatalogs() throws SQLException {
+ return new PostgresqlResultSet(impl.getCatalogs(), null);
+ }
+
+ public XResultSet getColumnPrivileges(Object arg0, String arg1, String arg2, String arg3) throws SQLException {
+ return new PostgresqlResultSet(impl.getColumnPrivileges(arg0, arg1, arg2, arg3), null);
+ }
+
+ public XResultSet getColumns(Object arg0, String arg1, String arg2, String arg3) throws SQLException {
+ XResultSet results = impl.getColumns(arg0, arg1, arg2, arg3);
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ ArrayList<ORowSetValue[]> table = new ArrayList<>();
+ while (results.next()) {
+ String tableCat = row.getString(1);
+ String tableSchem = row.getString(2);
+ String tableName = row.getString(3);
+ String columnName = row.getString(4);
+ short dataType = row.getShort(5);
+ String typeName = row.getString(6);
+ int columnSize = row.getInt(7);
+ int bufferLength = row.getInt(8); // FIXME: is it int?
+ int decimalDigits = row.getInt(9);
+ int numPrecRadix = row.getInt(10);
+ int nullable = row.getInt(11);
+ String remarks = row.getString(12);
+ String columnDef = row.getString(13);
+ int sqlDataType = row.getInt(14);
+ int sqlDateTimeSub = row.getInt(15);
+ int charOctetLength = row.getInt(16);
+ int ordinalPosition = row.getInt(17);
+ String isNullable = row.getString(18);
+
+ if (dataType == DataType.BIT) {
+ if (typeName.equals("bool")) {
+ dataType = DataType.BOOLEAN;
+ }
+ }
+
+ ORowSetValue[] rowOut = new ORowSetValue[18];
+ rowOut[0] = new ORowSetValue(tableCat);
+ rowOut[1] = new ORowSetValue(tableSchem);
+ rowOut[2] = new ORowSetValue(tableName);
+ rowOut[3] = new ORowSetValue(columnName);
+ rowOut[4] = new ORowSetValue(dataType);
+ rowOut[5] = new ORowSetValue(typeName);
+ rowOut[6] = new ORowSetValue(columnSize);
+ rowOut[7] = new ORowSetValue(bufferLength);
+ rowOut[8] = new ORowSetValue(decimalDigits);
+ rowOut[9] = new ORowSetValue(numPrecRadix);
+ rowOut[10] = new ORowSetValue(nullable);
+ rowOut[11] = new ORowSetValue(remarks);
+ rowOut[12] = new ORowSetValue(columnDef);
+ rowOut[13] = new ORowSetValue(sqlDataType);
+ rowOut[14] = new ORowSetValue(sqlDateTimeSub);
+ rowOut[15] = new ORowSetValue(charOctetLength);
+ rowOut[16] = new ORowSetValue(ordinalPosition);
+ rowOut[17] = new ORowSetValue(isNullable);
+ table.add(rowOut);
+ }
+ return new DatabaseMetaDataResultSet(results, table);
+ }
+
+ public XConnection getConnection() throws SQLException {
+ return connection;
+ }
+
+ public XResultSet getCrossReference(Object arg0, String arg1, String arg2, Object arg3, String arg4, String arg5) throws SQLException {
+ return new PostgresqlResultSet(impl.getCrossReference(arg0, arg1, arg2, arg3, arg4, arg5), null);
+ }
+
+ public String getDatabaseProductName() throws SQLException {
+ return impl.getDatabaseProductName();
+ }
+
+ public String getDatabaseProductVersion() throws SQLException {
+ return impl.getDatabaseProductVersion();
+ }
+
+ public int getDefaultTransactionIsolation() throws SQLException {
+ return impl.getDefaultTransactionIsolation();
+ }
+
+ public int getDriverMajorVersion() {
+ return impl.getDriverMajorVersion();
+ }
+
+ public int getDriverMinorVersion() {
+ return impl.getDriverMinorVersion();
+ }
+
+ public String getDriverName() throws SQLException {
+ return impl.getDriverName();
+ }
+
+ public String getDriverVersion() throws SQLException {
+ return impl.getDriverVersion();
+ }
+
+ public XResultSet getExportedKeys(Object arg0, String arg1, String arg2) throws SQLException {
+ return new PostgresqlResultSet(impl.getExportedKeys(arg0, arg1, arg2), null);
+ }
+
+ public String getExtraNameCharacters() throws SQLException {
+ return impl.getExtraNameCharacters();
+ }
+
+ public String getIdentifierQuoteString() throws SQLException {
+ return impl.getIdentifierQuoteString();
+ }
+
+ public XResultSet getImportedKeys(Object arg0, String arg1, String arg2) throws SQLException {
+ return new PostgresqlResultSet(impl.getImportedKeys(arg0, arg1, arg2), null);
+ }
+
+ public XResultSet getIndexInfo(Object arg0, String arg1, String arg2, boolean arg3, boolean arg4) throws SQLException {
+ return new PostgresqlResultSet(impl.getIndexInfo(arg0, arg1, arg2, arg3, arg4), null);
+ }
+
+ public int getMaxBinaryLiteralLength() throws SQLException {
+ return impl.getMaxBinaryLiteralLength();
+ }
+
+ public int getMaxCatalogNameLength() throws SQLException {
+ return impl.getMaxCatalogNameLength();
+ }
+
+ public int getMaxCharLiteralLength() throws SQLException {
+ return impl.getMaxCharLiteralLength();
+ }
+
+ public int getMaxColumnNameLength() throws SQLException {
+ return impl.getMaxColumnNameLength();
+ }
+
+ public int getMaxColumnsInGroupBy() throws SQLException {
+ return impl.getMaxColumnsInGroupBy();
+ }
+
+ public int getMaxColumnsInIndex() throws SQLException {
+ return impl.getMaxColumnsInIndex();
+ }
+
+ public int getMaxColumnsInOrderBy() throws SQLException {
+ return impl.getMaxColumnsInOrderBy();
+ }
+
+ public int getMaxColumnsInSelect() throws SQLException {
+ return impl.getMaxColumnsInSelect();
+ }
+
+ public int getMaxColumnsInTable() throws SQLException {
+ return impl.getMaxColumnsInTable();
+ }
+
+ public int getMaxConnections() throws SQLException {
+ return impl.getMaxConnections();
+ }
+
+ public int getMaxCursorNameLength() throws SQLException {
+ return impl.getMaxCursorNameLength();
+ }
+
+ public int getMaxIndexLength() throws SQLException {
+ return impl.getMaxIndexLength();
+ }
+
+ public int getMaxProcedureNameLength() throws SQLException {
+ return impl.getMaxProcedureNameLength();
+ }
+
+ public int getMaxRowSize() throws SQLException {
+ return impl.getMaxRowSize();
+ }
+
+ public int getMaxSchemaNameLength() throws SQLException {
+ return impl.getMaxSchemaNameLength();
+ }
+
+ public int getMaxStatementLength() throws SQLException {
+ return impl.getMaxStatementLength();
+ }
+
+ public int getMaxStatements() throws SQLException {
+ return impl.getMaxStatements();
+ }
+
+ public int getMaxTableNameLength() throws SQLException {
+ return impl.getMaxTableNameLength();
+ }
+
+ public int getMaxTablesInSelect() throws SQLException {
+ return impl.getMaxTablesInSelect();
+ }
+
+ public int getMaxUserNameLength() throws SQLException {
+ return impl.getMaxUserNameLength();
+ }
+
+ public String getNumericFunctions() throws SQLException {
+ return impl.getNumericFunctions();
+ }
+
+ public XResultSet getPrimaryKeys(Object arg0, String arg1, String arg2) throws SQLException {
+ return new PostgresqlResultSet(impl.getPrimaryKeys(arg0, arg1, arg2), null);
+ }
+
+ public XResultSet getProcedureColumns(Object arg0, String arg1, String arg2, String arg3) throws SQLException {
+ return new PostgresqlResultSet(impl.getProcedureColumns(arg0, arg1, arg2, arg3), null);
+ }
+
+ public String getProcedureTerm() throws SQLException {
+ return impl.getProcedureTerm();
+ }
+
+ public XResultSet getProcedures(Object arg0, String arg1, String arg2) throws SQLException {
+ return new PostgresqlResultSet(impl.getProcedures(arg0, arg1, arg2), null);
+ }
+
+ public String getSQLKeywords() throws SQLException {
+ return impl.getSQLKeywords();
+ }
+
+ public String getSchemaTerm() throws SQLException {
+ return impl.getSchemaTerm();
+ }
+
+ public XResultSet getSchemas() throws SQLException {
+ return new PostgresqlResultSet(impl.getSchemas(), null);
+ }
+
+ public String getSearchStringEscape() throws SQLException {
+ return impl.getSearchStringEscape();
+ }
+
+ public String getStringFunctions() throws SQLException {
+ return impl.getStringFunctions();
+ }
+
+ public String getSystemFunctions() throws SQLException {
+ return impl.getSystemFunctions();
+ }
+
+ public XResultSet getTablePrivileges(Object arg0, String arg1, String arg2) throws SQLException {
+ return new PostgresqlResultSet(impl.getTablePrivileges(arg0, arg1, arg2), null);
+ }
+
+ public XResultSet getTableTypes() throws SQLException {
+ return new PostgresqlResultSet(impl.getTableTypes(), null);
+ }
+
+ public XResultSet getTables(Object arg0, String arg1, String arg2, String[] arg3) throws SQLException {
+ return new PostgresqlResultSet(impl.getTables(arg0, arg1, arg2, arg3), null);
+ }
+
+ public String getTimeDateFunctions() throws SQLException {
+ return impl.getTimeDateFunctions();
+ }
+
+ public XResultSet getTypeInfo() throws SQLException {
+ XResultSet results = impl.getTypeInfo();
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ ArrayList<ORowSetValue[]> table = new ArrayList<>();
+ while (results.next()) {
+ String typeName = row.getString(1);
+ short dataType = row.getShort(2);
+ int precision = row.getInt(3);
+ String literalPrefix = row.getString(4);
+ String literalSuffix = row.getString(5);
+ String createParams = row.getString(6);
+ short nullable = row.getShort(7);
+ boolean caseSensitive = row.getBoolean(8);
+ short searchable = row.getShort(9);
+ boolean unsignedAttribute = row.getBoolean(10);
+ boolean fixedPrecScale = row.getBoolean(11);
+ boolean autoIncrement = row.getBoolean(12);
+ String localTypeName = row.getString(13);
+ short minimumScale = row.getShort(14);
+ short maximumScale = row.getShort(15);
+ int sqlDataType = row.getInt(16);
+ int sqlDateTimeSub = row.getInt(17);
+ int numPrecRadix = row.getInt(18);
+
+ if (dataType == DataType.BIT) {
+ if (typeName.equals("bit")) {
+ // but the editor sees multi-bit columns as single bit
+ // and single bit can't be edited either: syntax error
+ createParams = "length";
+ } else if (typeName.equals("bool")) {
+ dataType = DataType.BOOLEAN;
+ }
+ }
+ if ((dataType == DataType.CHAR || dataType == DataType.VARCHAR)) {
+ precision = 10485760;
+ createParams = "length";
+ }
+
+ ORowSetValue[] rowOut = new ORowSetValue[18];
+ rowOut[0] = new ORowSetValue(typeName);
+ rowOut[1] = new ORowSetValue(dataType);
+ rowOut[2] = new ORowSetValue(precision);
+ rowOut[3] = new ORowSetValue(literalPrefix);
+ rowOut[4] = new ORowSetValue(literalSuffix);
+ rowOut[5] = new ORowSetValue(createParams);
+ rowOut[6] = new ORowSetValue(nullable);
+ rowOut[7] = new ORowSetValue(caseSensitive);
+ rowOut[8] = new ORowSetValue(searchable);
+ rowOut[9] = new ORowSetValue(unsignedAttribute);
+ rowOut[10] = new ORowSetValue(fixedPrecScale);
+ rowOut[11] = new ORowSetValue(autoIncrement);
+ rowOut[12] = new ORowSetValue(localTypeName);
+ rowOut[13] = new ORowSetValue(minimumScale);
+ rowOut[14] = new ORowSetValue(maximumScale);
+ rowOut[15] = new ORowSetValue(sqlDataType);
+ rowOut[16] = new ORowSetValue(sqlDateTimeSub);
+ rowOut[17] = new ORowSetValue(numPrecRadix);
+ table.add(rowOut);
+ //System.out.println(String.format("type %s, data type %d, SQL type %d, precision %d, createParams %s", typeName, dataType, sqlDataType, precision, createParams));
+ }
+ return new DatabaseMetaDataResultSet(results, table);
+ }
+
+ public XResultSet getUDTs(Object arg0, String arg1, String arg2, int[] arg3) throws SQLException {
+ return new PostgresqlResultSet(impl.getUDTs(arg0, arg1, arg2, arg3), null);
+ }
+
+ public String getURL() throws SQLException {
+ return url;
+ }
+
+ public String getUserName() throws SQLException {
+ return impl.getUserName();
+ }
+
+ public XResultSet getVersionColumns(Object arg0, String arg1, String arg2) throws SQLException {
+ return new PostgresqlResultSet(impl.getVersionColumns(arg0, arg1, arg2), null);
+ }
+
+ public boolean insertsAreDetected(int arg0) throws SQLException {
+ return impl.insertsAreDetected(arg0);
+ }
+
+ public boolean isCatalogAtStart() throws SQLException {
+ return impl.isCatalogAtStart();
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return impl.isReadOnly();
+ }
+
+ public boolean nullPlusNonNullIsNull() throws SQLException {
+ return impl.nullPlusNonNullIsNull();
+ }
+
+ public boolean nullsAreSortedAtEnd() throws SQLException {
+ return impl.nullsAreSortedAtEnd();
+ }
+
+ public boolean nullsAreSortedAtStart() throws SQLException {
+ return impl.nullsAreSortedAtStart();
+ }
+
+ public boolean nullsAreSortedHigh() throws SQLException {
+ return impl.nullsAreSortedHigh();
+ }
+
+ public boolean nullsAreSortedLow() throws SQLException {
+ return impl.nullsAreSortedLow();
+ }
+
+ public boolean othersDeletesAreVisible(int arg0) throws SQLException {
+ return impl.othersDeletesAreVisible(arg0);
+ }
+
+ public boolean othersInsertsAreVisible(int arg0) throws SQLException {
+ return impl.othersInsertsAreVisible(arg0);
+ }
+
+ public boolean othersUpdatesAreVisible(int arg0) throws SQLException {
+ return impl.othersUpdatesAreVisible(arg0);
+ }
+
+ public boolean ownDeletesAreVisible(int arg0) throws SQLException {
+ return impl.ownDeletesAreVisible(arg0);
+ }
+
+ public boolean ownInsertsAreVisible(int arg0) throws SQLException {
+ return impl.ownInsertsAreVisible(arg0);
+ }
+
+ public boolean ownUpdatesAreVisible(int arg0) throws SQLException {
+ return impl.ownUpdatesAreVisible(arg0);
+ }
+
+ public boolean storesLowerCaseIdentifiers() throws SQLException {
+ return impl.storesLowerCaseIdentifiers();
+ }
+
+ public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+ return impl.storesLowerCaseQuotedIdentifiers();
+ }
+
+ public boolean storesMixedCaseIdentifiers() throws SQLException {
+ return impl.storesMixedCaseIdentifiers();
+ }
+
+ public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+ return impl.storesMixedCaseQuotedIdentifiers();
+ }
+
+ public boolean storesUpperCaseIdentifiers() throws SQLException {
+ return impl.storesUpperCaseIdentifiers();
+ }
+
+ public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+ return impl.storesUpperCaseQuotedIdentifiers();
+ }
+
+ public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+ return impl.supportsANSI92EntryLevelSQL();
+ }
+
+ public boolean supportsANSI92FullSQL() throws SQLException {
+ return impl.supportsANSI92FullSQL();
+ }
+
+ public boolean supportsANSI92IntermediateSQL() throws SQLException {
+ return impl.supportsANSI92IntermediateSQL();
+ }
+
+ public boolean supportsAlterTableWithAddColumn() throws SQLException {
+ return impl.supportsAlterTableWithAddColumn();
+ }
+
+ public boolean supportsAlterTableWithDropColumn() throws SQLException {
+ return impl.supportsAlterTableWithDropColumn();
+ }
+
+ public boolean supportsBatchUpdates() throws SQLException {
+ return impl.supportsBatchUpdates();
+ }
+
+ public boolean supportsCatalogsInDataManipulation() throws SQLException {
+ return impl.supportsCatalogsInDataManipulation();
+ }
+
+ public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+ return impl.supportsCatalogsInIndexDefinitions();
+ }
+
+ public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+ return impl.supportsCatalogsInPrivilegeDefinitions();
+ }
+
+ public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+ return impl.supportsCatalogsInProcedureCalls();
+ }
+
+ public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+ return impl.supportsCatalogsInTableDefinitions();
+ }
+
+ public boolean supportsColumnAliasing() throws SQLException {
+ return impl.supportsColumnAliasing();
+ }
+
+ public boolean supportsConvert(int arg0, int arg1) throws SQLException {
+ return impl.supportsConvert(arg0, arg1);
+ }
+
+ public boolean supportsCoreSQLGrammar() throws SQLException {
+ return impl.supportsCoreSQLGrammar();
+ }
+
+ public boolean supportsCorrelatedSubqueries() throws SQLException {
+ return impl.supportsCorrelatedSubqueries();
+ }
+
+ public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
+ return impl.supportsDataDefinitionAndDataManipulationTransactions();
+ }
+
+ public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+ return impl.supportsDataManipulationTransactionsOnly();
+ }
+
+ public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+ return impl.supportsDifferentTableCorrelationNames();
+ }
+
+ public boolean supportsExpressionsInOrderBy() throws SQLException {
+ return impl.supportsExpressionsInOrderBy();
+ }
+
+ public boolean supportsExtendedSQLGrammar() throws SQLException {
+ return impl.supportsExtendedSQLGrammar();
+ }
+
+ public boolean supportsFullOuterJoins() throws SQLException {
+ return impl.supportsFullOuterJoins();
+ }
+
+ public boolean supportsGroupBy() throws SQLException {
+ return impl.supportsGroupBy();
+ }
+
+ public boolean supportsGroupByBeyondSelect() throws SQLException {
+ return impl.supportsGroupByBeyondSelect();
+ }
+
+ public boolean supportsGroupByUnrelated() throws SQLException {
+ return impl.supportsGroupByUnrelated();
+ }
+
+ public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+ return impl.supportsIntegrityEnhancementFacility();
+ }
+
+ public boolean supportsLikeEscapeClause() throws SQLException {
+ return impl.supportsLikeEscapeClause();
+ }
+
+ public boolean supportsLimitedOuterJoins() throws SQLException {
+ return impl.supportsLimitedOuterJoins();
+ }
+
+ public boolean supportsMinimumSQLGrammar() throws SQLException {
+ return impl.supportsMinimumSQLGrammar();
+ }
+
+ public boolean supportsMixedCaseIdentifiers() throws SQLException {
+ return impl.supportsMixedCaseIdentifiers();
+ }
+
+ public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+ return impl.supportsMixedCaseQuotedIdentifiers();
+ }
+
+ public boolean supportsMultipleResultSets() throws SQLException {
+ return impl.supportsMultipleResultSets();
+ }
+
+ public boolean supportsMultipleTransactions() throws SQLException {
+ return impl.supportsMultipleTransactions();
+ }
+
+ public boolean supportsNonNullableColumns() throws SQLException {
+ return impl.supportsNonNullableColumns();
+ }
+
+ public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+ return impl.supportsOpenCursorsAcrossCommit();
+ }
+
+ public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+ return impl.supportsOpenCursorsAcrossRollback();
+ }
+
+ public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+ return impl.supportsOpenStatementsAcrossCommit();
+ }
+
+ public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+ return impl.supportsOpenStatementsAcrossRollback();
+ }
+
+ public boolean supportsOrderByUnrelated() throws SQLException {
+ return impl.supportsOrderByUnrelated();
+ }
+
+ public boolean supportsOuterJoins() throws SQLException {
+ return impl.supportsOuterJoins();
+ }
+
+ public boolean supportsPositionedDelete() throws SQLException {
+ return impl.supportsPositionedDelete();
+ }
+
+ public boolean supportsPositionedUpdate() throws SQLException {
+ return impl.supportsPositionedUpdate();
+ }
+
+ public boolean supportsResultSetConcurrency(int arg0, int arg1) throws SQLException {
+ return impl.supportsResultSetConcurrency(arg0, arg1);
+ }
+
+ public boolean supportsResultSetType(int arg0) throws SQLException {
+ return impl.supportsResultSetType(arg0);
+ }
+
+ public boolean supportsSchemasInDataManipulation() throws SQLException {
+ return impl.supportsSchemasInDataManipulation();
+ }
+
+ public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+ return impl.supportsSchemasInIndexDefinitions();
+ }
+
+ public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+ return impl.supportsSchemasInPrivilegeDefinitions();
+ }
+
+ public boolean supportsSchemasInProcedureCalls() throws SQLException {
+ return impl.supportsSchemasInProcedureCalls();
+ }
+
+ public boolean supportsSchemasInTableDefinitions() throws SQLException {
+ return impl.supportsSchemasInTableDefinitions();
+ }
+
+ public boolean supportsSelectForUpdate() throws SQLException {
+ return impl.supportsSelectForUpdate();
+ }
+
+ public boolean supportsStoredProcedures() throws SQLException {
+ return impl.supportsStoredProcedures();
+ }
+
+ public boolean supportsSubqueriesInComparisons() throws SQLException {
+ return impl.supportsSubqueriesInComparisons();
+ }
+
+ public boolean supportsSubqueriesInExists() throws SQLException {
+ return impl.supportsSubqueriesInExists();
+ }
+
+ public boolean supportsSubqueriesInIns() throws SQLException {
+ return impl.supportsSubqueriesInIns();
+ }
+
+ public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+ return impl.supportsSubqueriesInQuantifieds();
+ }
+
+ public boolean supportsTableCorrelationNames() throws SQLException {
+ return impl.supportsTableCorrelationNames();
+ }
+
+ public boolean supportsTransactionIsolationLevel(int arg0) throws SQLException {
+ return impl.supportsTransactionIsolationLevel(arg0);
+ }
+
+ public boolean supportsTransactions() throws SQLException {
+ return impl.supportsTransactions();
+ }
+
+ public boolean supportsTypeConversion() throws SQLException {
+ return impl.supportsTypeConversion();
+ }
+
+ public boolean supportsUnion() throws SQLException {
+ return impl.supportsUnion();
+ }
+
+ public boolean supportsUnionAll() throws SQLException {
+ return impl.supportsUnionAll();
+ }
+
+ public boolean updatesAreDetected(int arg0) throws SQLException {
+ return impl.updatesAreDetected(arg0);
+ }
+
+ public boolean usesLocalFilePerTable() throws SQLException {
+ return impl.usesLocalFilePerTable();
+ }
+
+ public boolean usesLocalFiles() throws SQLException {
+ return impl.usesLocalFiles();
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlDriver.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlDriver.java
new file mode 100644
index 000000000000..43fd434f2037
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlDriver.java
@@ -0,0 +1,199 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lib.uno.helper.ComponentBase;
+import com.sun.star.lib.uno.helper.Factory;
+import com.sun.star.sdbc.DriverPropertyInfo;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbc.XDriver;
+import com.sun.star.sdbc.XDriverManager;
+import com.sun.star.sdbcx.XDataDefinitionSupplier;
+import com.sun.star.sdbcx.XTablesSupplier;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.SharedResources;
+import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState;
+import com.sun.star.uno.Exception;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+
+public class PostgresqlDriver extends ComponentBase implements XServiceInfo, XDriver, XDataDefinitionSupplier {
+ private static String[] services = new String[] {
+ "com.sun.star.sdbc.Driver",
+ "com.sun.star.sdbcx.Driver"
+ };
+ private XComponentContext componentContext;
+ private AtomicBoolean isDisposed = new AtomicBoolean(false);
+
+ public static XSingleComponentFactory __getComponentFactory(String implName) {
+ XSingleComponentFactory xSingleComponentFactory = null;
+ if (implName.equals(getImplementationNameStatic())) {
+ xSingleComponentFactory = Factory.createComponentFactory(PostgresqlDriver.class,
+ getImplementationNameStatic(), services);
+ }
+ return xSingleComponentFactory;
+ }
+
+ public PostgresqlDriver(XComponentContext componentContext) {
+ this.componentContext = componentContext;
+ SharedResources.registerClient(componentContext);
+ }
+
+ private static String getImplementationNameStatic() {
+ return PostgresqlDriver.class.getName();
+ }
+
+ // XComponent:
+
+ @Override
+ protected void postDisposing() {
+ isDisposed.set(true);
+ componentContext = null;
+ SharedResources.revokeClient();
+ }
+
+ private void checkDisposed() throws DisposedException {
+ if (isDisposed.get()) {
+ throw new DisposedException();
+ }
+ }
+
+ // XServiceInfo:
+
+ @Override
+ public String getImplementationName() {
+ return getImplementationNameStatic();
+ }
+
+ @Override
+ public String[] getSupportedServiceNames() {
+ return services.clone();
+ }
+
+ @Override
+ public boolean supportsService(String serviceName) {
+ for (String service : services) {
+ if (service.equals(serviceName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // XDriver:
+
+ @Override
+ public boolean acceptsURL(String url) throws SQLException {
+ return url.startsWith("sdbc:postgresql:jdbc:");
+ }
+
+ @Override
+ public XConnection connect(String url, PropertyValue[] info) throws SQLException {
+ checkDisposed();
+ XConnection connection = null;
+ if (acceptsURL(url)) {
+ String jdbcUrl = transformUrl(url);
+ System.out.println("Using SDBC URL " + url + " and JDBC URL " + jdbcUrl);
+
+ try {
+ Object driverManagerObject = componentContext.getServiceManager().createInstanceWithContext(
+ "com.sun.star.sdbc.DriverManager", componentContext);
+ XDriverManager driverManager = UnoRuntime.queryInterface(XDriverManager.class, driverManagerObject);
+
+ ArrayList<PropertyValue> properties = new ArrayList<>();
+ boolean haveJavaClass = false;
+ for (PropertyValue property : info) {
+ if (property.Name.equals("JavaDriverClass")) {
+ haveJavaClass = true;
+ }
+ properties.add(property);
+ }
+ if (!haveJavaClass) {
+ PropertyValue javaClassProperty = new PropertyValue();
+ javaClassProperty.Name = "JavaDriverClass";
+ javaClassProperty.Value = "org.postgresql.Driver";
+ properties.add(javaClassProperty);
+ }
+ PropertyValue[] jdbcInfo = properties.toArray(new PropertyValue[properties.size()]);
+
+ connection = driverManager.getConnectionWithInfo(jdbcUrl, jdbcInfo);
+ if (connection != null) {
+ connection = new PostgresqlConnection(connection, url);
+ }
+ } catch (SQLException sqlException) {
+ throw sqlException;
+ } catch (Exception exception) {
+ throw new SQLException(exception.getMessage(), this, StandardSQLState.SQL_UNABLE_TO_CONNECT.text(), 0, exception);
+ }
+ }
+ return connection;
+ }
+
+ @Override
+ public int getMajorVersion() {
+ return 1;
+ }
+
+ @Override
+ public int getMinorVersion() {
+ return 0;
+ }
+
+ @Override
+ public DriverPropertyInfo[] getPropertyInfo(String url, PropertyValue[] info) throws SQLException {
+ if (!acceptsURL(url)) {
+ return new DriverPropertyInfo[0];
+ }
+ return new DriverPropertyInfo [] {
+ new DriverPropertyInfo("JavaClassName", "The JDBC driver class name.", true,
+ "com.postgresql.Driver", new String[0]),
+ };
+ }
+
+ private static String transformUrl(String url) {
+ // 012345678901234567890
+ // sdbc:postgresql:jdbc:
+ return "jdbc:postgresql:" + url.substring(21);
+ }
+
+ // XDataDefinitionSupplier:
+
+ public XTablesSupplier getDataDefinitionByConnection(XConnection connection) throws SQLException {
+ checkDisposed();
+ return new PostgresqlCatalog((PostgresqlConnection)connection);
+ }
+
+ public XTablesSupplier getDataDefinitionByURL(String url, PropertyValue[] info) throws SQLException {
+ checkDisposed();
+ if (!acceptsURL(url)) {
+ throw new SQLException(); // FIXME
+ }
+ return getDataDefinitionByConnection(connect(url, info));
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlPreparedStatement.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlPreparedStatement.java
new file mode 100644
index 000000000000..ff4b99684a5a
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlPreparedStatement.java
@@ -0,0 +1,348 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertyChangeListener;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+import com.sun.star.beans.XVetoableChangeListener;
+import com.sun.star.io.XInputStream;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lib.uno.helper.ComponentBase;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XArray;
+import com.sun.star.sdbc.XBlob;
+import com.sun.star.sdbc.XClob;
+import com.sun.star.sdbc.XCloseable;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbc.XMultipleResults;
+import com.sun.star.sdbc.XParameters;
+import com.sun.star.sdbc.XPreparedBatchExecution;
+import com.sun.star.sdbc.XPreparedStatement;
+import com.sun.star.sdbc.XRef;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XResultSetMetaData;
+import com.sun.star.sdbc.XResultSetMetaDataSupplier;
+import com.sun.star.sdbc.XWarningsSupplier;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.util.Date;
+import com.sun.star.util.DateTime;
+import com.sun.star.util.Time;
+import com.sun.star.util.XCancellable;
+
+public class PostgresqlPreparedStatement extends ComponentBase
+ implements XPreparedStatement, XCloseable, XPropertySet, XCancellable, XResultSetMetaDataSupplier, XParameters, XPreparedBatchExecution,
+ XWarningsSupplier, XMultipleResults {
+
+ private XPreparedStatement impl;
+ private XCloseable implCloseable;
+ private XPropertySet implPropertySet;
+ private XCancellable implCancellable;
+ private XResultSetMetaDataSupplier implResultSetMetaDataSupplier;
+ private XParameters implParameters;
+ private XPreparedBatchExecution implPreparedBatchExecution;
+ private XWarningsSupplier implWarningsSupplier;
+ private XMultipleResults implMultipleResults;
+ private XConnection connection;
+ private AtomicBoolean isDisposed = new AtomicBoolean(false);
+
+ public PostgresqlPreparedStatement(XPreparedStatement impl, XConnection connection) {
+ this.impl = impl;
+ this.implCloseable = UnoRuntime.queryInterface(XCloseable.class, impl);
+ this.implPropertySet = UnoRuntime.queryInterface(XPropertySet.class, impl);
+ this.implCancellable = UnoRuntime.queryInterface(XCancellable.class, impl);
+ this.implResultSetMetaDataSupplier = UnoRuntime.queryInterface(XResultSetMetaDataSupplier.class, impl);
+ this.implParameters = UnoRuntime.queryInterface(XParameters.class, impl);
+ this.implPreparedBatchExecution = UnoRuntime.queryInterface(XPreparedBatchExecution.class, impl);
+ this.implWarningsSupplier = UnoRuntime.queryInterface(XWarningsSupplier.class, impl);
+ this.implMultipleResults = UnoRuntime.queryInterface(XMultipleResults.class, impl);
+ this.connection = connection;
+ }
+
+ // XComponentBase:
+
+ @Override
+ protected void postDisposing() {
+ isDisposed.set(true);
+ try {
+ implCloseable.close();
+ } catch (SQLException sqlException) {
+ }
+ }
+
+ private void checkDisposed() {
+ if (isDisposed.get()) {
+ throw new DisposedException();
+ }
+ }
+
+ // XPreparedStatement:
+
+ public boolean execute() throws SQLException {
+ checkDisposed();
+ return impl.execute();
+ }
+
+ public XResultSet executeQuery() throws SQLException {
+ checkDisposed();
+ return new PostgresqlResultSet(impl.executeQuery(), this);
+ }
+
+ public int executeUpdate() throws SQLException {
+ checkDisposed();
+ return impl.executeUpdate();
+ }
+
+ public XConnection getConnection() throws SQLException {
+ checkDisposed();
+ return connection;
+ }
+
+ // XCloseable:
+
+ public void close() throws SQLException {
+ dispose();
+ }
+
+ // XPropertySet:
+
+ public void addPropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.addPropertyChangeListener(arg0, arg1);
+ }
+
+ public void addVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.addVetoableChangeListener(arg0, arg1);
+ }
+
+ public XPropertySetInfo getPropertySetInfo() {
+ checkDisposed();
+ return implPropertySet.getPropertySetInfo();
+ }
+
+ public Object getPropertyValue(String arg0) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ return implPropertySet.getPropertyValue(arg0);
+ }
+
+ public void removePropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.removePropertyChangeListener(arg0, arg1);
+ }
+
+ public void removeVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.removeVetoableChangeListener(arg0, arg1);
+ }
+
+ public void setPropertyValue(String arg0, Object arg1)
+ throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.setPropertyValue(arg0, arg1);
+ }
+
+ // XCancellable:
+
+ public void cancel() {
+ checkDisposed();
+ implCancellable.cancel();
+ }
+
+ // XResultSetMetaDataSupplier:
+
+ public XResultSetMetaData getMetaData() throws SQLException {
+ checkDisposed();
+ return new PostgresqlResultSetMetaData(implResultSetMetaDataSupplier.getMetaData());
+ }
+
+ // XParameters:
+
+ public void clearParameters() throws SQLException {
+ checkDisposed();
+ implParameters.clearParameters();
+ }
+
+ public void setArray(int arg0, XArray arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setArray(arg0, arg1);
+ }
+
+ public void setBinaryStream(int arg0, XInputStream arg1, int arg2) throws SQLException {
+ checkDisposed();
+ implParameters.setBinaryStream(arg0, arg1, arg2);
+ }
+
+ public void setBlob(int arg0, XBlob arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setBlob(arg0, arg1);
+ }
+
+ public void setBoolean(int arg0, boolean arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setBoolean(arg0, arg1);
+ }
+
+ public void setByte(int arg0, byte arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setByte(arg0, arg1);
+ }
+
+ public void setBytes(int arg0, byte[] arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setBytes(arg0, arg1);
+ }
+
+ public void setCharacterStream(int arg0, XInputStream arg1, int arg2) throws SQLException {
+ checkDisposed();
+ implParameters.setCharacterStream(arg0, arg1, arg2);
+ }
+
+ public void setClob(int arg0, XClob arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setClob(arg0, arg1);
+ }
+
+ public void setDate(int arg0, Date arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setDate(arg0, arg1);
+ }
+
+ public void setDouble(int arg0, double arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setDouble(arg0, arg1);
+ }
+
+ public void setFloat(int arg0, float arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setFloat(arg0, arg1);
+ }
+
+ public void setInt(int arg0, int arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setInt(arg0, arg1);
+ }
+
+ public void setLong(int arg0, long arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setLong(arg0, arg1);
+ }
+
+ public void setNull(int arg0, int arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setNull(arg0, arg1);
+ }
+
+ public void setObject(int arg0, Object arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setObject(arg0, arg1);
+ }
+
+ public void setObjectNull(int arg0, int arg1, String arg2) throws SQLException {
+ checkDisposed();
+ implParameters.setObjectNull(arg0, arg1, arg2);
+ }
+
+ public void setObjectWithInfo(int arg0, Object arg1, int arg2, int arg3) throws SQLException {
+ checkDisposed();
+ implParameters.setObjectWithInfo(arg0, arg1, arg2, arg3);
+ }
+
+ public void setRef(int arg0, XRef arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setRef(arg0, arg1);
+ }
+
+ public void setShort(int arg0, short arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setShort(arg0, arg1);
+ }
+
+ public void setString(int arg0, String arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setString(arg0, arg1);
+ }
+
+ public void setTime(int arg0, Time arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setTime(arg0, arg1);
+ }
+
+ public void setTimestamp(int arg0, DateTime arg1) throws SQLException {
+ checkDisposed();
+ implParameters.setTimestamp(arg0, arg1);
+ }
+
+ // XPreparedBatchExecution:
+
+ public void addBatch() throws SQLException {
+ checkDisposed();
+ implPreparedBatchExecution.addBatch();
+ }
+
+ public void clearBatch() throws SQLException {
+ checkDisposed();
+ implPreparedBatchExecution.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ checkDisposed();
+ return implPreparedBatchExecution.executeBatch();
+ }
+
+ // XWarningsSupplier:
+
+ public void clearWarnings() throws SQLException {
+ checkDisposed();
+ implWarningsSupplier.clearWarnings();
+ }
+
+ public Object getWarnings() throws SQLException {
+ checkDisposed();
+ return implWarningsSupplier.getWarnings();
+ }
+
+ // XMultipleResults:
+
+ public boolean getMoreResults() throws SQLException {
+ checkDisposed();
+ return implMultipleResults.getMoreResults();
+ }
+
+ public XResultSet getResultSet() throws SQLException {
+ checkDisposed();
+ return new PostgresqlResultSet(implMultipleResults.getResultSet(), this);
+ }
+
+ public int getUpdateCount() throws SQLException {
+ checkDisposed();
+ return implMultipleResults.getUpdateCount();
+ }
+
+
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlResultSet.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlResultSet.java
new file mode 100644
index 000000000000..1ba5d62cbedb
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlResultSet.java
@@ -0,0 +1,495 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertyChangeListener;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+import com.sun.star.beans.XVetoableChangeListener;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.io.XInputStream;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lib.uno.helper.ComponentBase;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XArray;
+import com.sun.star.sdbc.XBlob;
+import com.sun.star.sdbc.XClob;
+import com.sun.star.sdbc.XCloseable;
+import com.sun.star.sdbc.XColumnLocate;
+import com.sun.star.sdbc.XRef;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XResultSetMetaData;
+import com.sun.star.sdbc.XResultSetMetaDataSupplier;
+import com.sun.star.sdbc.XResultSetUpdate;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbc.XRowUpdate;
+import com.sun.star.sdbc.XWarningsSupplier;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.util.Date;
+import com.sun.star.util.DateTime;
+import com.sun.star.util.Time;
+import com.sun.star.util.XCancellable;
+
+public class PostgresqlResultSet extends ComponentBase
+ implements XResultSet, XRow, XResultSetMetaDataSupplier, XCancellable, XWarningsSupplier, XResultSetUpdate,
+ XRowUpdate, XCloseable, XColumnLocate, XPropertySet {
+
+ private XResultSet impl;
+ private XRow implRow;
+ private XResultSetMetaDataSupplier implResultSetMetaDataSupplier;
+ private XCancellable implCancellable;
+ private XWarningsSupplier implWarningsSupplier;
+ private XResultSetUpdate implResultSetUpdate;
+ private XRowUpdate implRowUpdate;
+ private XCloseable implCloseable;
+ private XColumnLocate implColumnLocate;
+ private XPropertySet implPropertySet;
+ private Object statement;
+ private AtomicBoolean isDisposed = new AtomicBoolean(false);
+
+ public PostgresqlResultSet(XResultSet impl, Object statement) {
+ this.impl = impl;
+ this.implRow = UnoRuntime.queryInterface(XRow.class, impl);
+ this.implResultSetMetaDataSupplier = UnoRuntime.queryInterface(XResultSetMetaDataSupplier.class, impl);
+ this.implCancellable = UnoRuntime.queryInterface(XCancellable.class, impl);
+ this.implWarningsSupplier = UnoRuntime.queryInterface(XWarningsSupplier.class, impl);
+ this.implResultSetUpdate = UnoRuntime.queryInterface(XResultSetUpdate.class, impl);
+ this.implRowUpdate = UnoRuntime.queryInterface(XRowUpdate.class, impl);
+ this.implCloseable = UnoRuntime.queryInterface(XCloseable.class, impl);
+ this.implColumnLocate = UnoRuntime.queryInterface(XColumnLocate.class, impl);
+ this.implPropertySet = UnoRuntime.queryInterface(XPropertySet.class, impl);
+ this.statement = statement;
+ }
+
+ // XComponent:
+
+ @Override
+ protected synchronized void postDisposing() {
+ isDisposed.set(true);
+ try {
+ implCloseable.close();
+ } catch (SQLException sqlException) {
+ }
+ };
+
+ private void checkDisposed() throws DisposedException {
+ if (isDisposed.get()) {
+ throw new DisposedException();
+ }
+ }
+
+ // XCloseable:
+
+ public void close() throws SQLException {
+ dispose();
+ }
+
+ // XResultSet:
+
+ public boolean absolute(int arg0) throws SQLException {
+ checkDisposed();
+ return impl.absolute(arg0);
+ }
+
+ public void afterLast() throws SQLException {
+ checkDisposed();
+ impl.afterLast();
+ }
+
+ public void beforeFirst() throws SQLException {
+ checkDisposed();
+ impl.beforeFirst();
+ }
+
+ public boolean first() throws SQLException {
+ checkDisposed();
+ return impl.first();
+ }
+
+ public int getRow() throws SQLException {
+ checkDisposed();
+ return impl.getRow();
+ }
+
+ public Object getStatement() throws SQLException {
+ checkDisposed();
+ return statement;
+ }
+
+ public boolean isAfterLast() throws SQLException {
+ checkDisposed();
+ return impl.isAfterLast();
+ }
+
+ public boolean isBeforeFirst() throws SQLException {
+ checkDisposed();
+ return impl.isBeforeFirst();
+ }
+
+ public boolean isFirst() throws SQLException {
+ checkDisposed();
+ return impl.isFirst();
+ }
+
+ public boolean isLast() throws SQLException {
+ checkDisposed();
+ return impl.isLast();
+ }
+
+ public boolean last() throws SQLException {
+ checkDisposed();
+ return impl.last();
+ }
+
+ public boolean next() throws SQLException {
+ checkDisposed();
+ return impl.next();
+ }
+
+ public boolean previous() throws SQLException {
+ checkDisposed();
+ return impl.previous();
+ }
+
+ public void refreshRow() throws SQLException {
+ checkDisposed();
+ impl.refreshRow();
+ }
+
+ public boolean relative(int arg0) throws SQLException {
+ checkDisposed();
+ return impl.relative(arg0);
+ }
+
+ public boolean rowDeleted() throws SQLException {
+ checkDisposed();
+ return impl.rowDeleted();
+ }
+
+ public boolean rowInserted() throws SQLException {
+ checkDisposed();
+ return impl.rowInserted();
+ }
+
+ public boolean rowUpdated() throws SQLException {
+ checkDisposed();
+ return impl.rowUpdated();
+ }
+
+ // XRow:
+
+ public XArray getArray(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getArray(arg0);
+ }
+
+ public XInputStream getBinaryStream(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getBinaryStream(arg0);
+ }
+
+ public XBlob getBlob(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getBlob(arg0);
+ }
+
+ public boolean getBoolean(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getBoolean(arg0);
+ }
+
+ public byte getByte(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getByte(arg0);
+ }
+
+ public byte[] getBytes(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getBytes(arg0);
+ }
+
+ public XInputStream getCharacterStream(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getCharacterStream(arg0);
+ }
+
+ public XClob getClob(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getClob(arg0);
+ }
+
+ public Date getDate(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getDate(arg0);
+ }
+
+ public double getDouble(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getDouble(arg0);
+ }
+
+ public float getFloat(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getFloat(arg0);
+ }
+
+ public int getInt(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getInt(arg0);
+ }
+
+ public long getLong(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getLong(arg0);
+ }
+
+ public Object getObject(int arg0, XNameAccess arg1) throws SQLException {
+ checkDisposed();
+ return implRow.getObject(arg0, arg1);
+ }
+
+ public XRef getRef(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getRef(arg0);
+ }
+
+ public short getShort(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getShort(arg0);
+ }
+
+ public String getString(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getString(arg0);
+ }
+
+ public Time getTime(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getTime(arg0);
+ }
+
+ public DateTime getTimestamp(int arg0) throws SQLException {
+ checkDisposed();
+ return implRow.getTimestamp(arg0);
+ }
+
+ public boolean wasNull() throws SQLException {
+ checkDisposed();
+ return implRow.wasNull();
+ }
+
+ // XResultSetMetaDataSupplier:
+
+ public XResultSetMetaData getMetaData() throws SQLException {
+ checkDisposed();
+ return new PostgresqlResultSetMetaData(implResultSetMetaDataSupplier.getMetaData());
+ }
+
+ // XCancellable:
+
+ public void cancel() {
+ checkDisposed();
+ implCancellable.cancel();
+ }
+
+ // XWarningsSupplier:
+
+ public void clearWarnings() throws SQLException {
+ checkDisposed();
+ implWarningsSupplier.clearWarnings();
+ }
+
+ public Object getWarnings() throws SQLException {
+ checkDisposed();
+ return implWarningsSupplier.getWarnings();
+ }
+
+ // XResultSetUpdate:
+
+ public void cancelRowUpdates() throws SQLException {
+ checkDisposed();
+ implResultSetUpdate.cancelRowUpdates();
+ }
+
+ public void deleteRow() throws SQLException {
+ checkDisposed();
+ implResultSetUpdate.deleteRow();
+ }
+
+ public void insertRow() throws SQLException {
+ checkDisposed();
+ implResultSetUpdate.insertRow();
+ }
+
+ public void moveToCurrentRow() throws SQLException {
+ checkDisposed();
+ implResultSetUpdate.moveToCurrentRow();
+ }
+
+ public void moveToInsertRow() throws SQLException {
+ checkDisposed();
+ implResultSetUpdate.moveToInsertRow();
+ }
+
+ public void updateRow() throws SQLException {
+ checkDisposed();
+ implResultSetUpdate.updateRow();
+ }
+
+ // XRowUpdate:
+
+ public void updateBinaryStream(int arg0, XInputStream arg1, int arg2) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateBinaryStream(arg0, arg1, arg2);
+ }
+
+ public void updateBoolean(int arg0, boolean arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateBoolean(arg0, arg1);
+ }
+
+ public void updateByte(int arg0, byte arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateByte(arg0, arg1);
+ }
+
+ public void updateBytes(int arg0, byte[] arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateBytes(arg0, arg1);
+ }
+
+ public void updateCharacterStream(int arg0, XInputStream arg1, int arg2) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateCharacterStream(arg0, arg1, arg2);
+ }
+
+ public void updateDate(int arg0, Date arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateDate(arg0, arg1);
+ }
+
+ public void updateDouble(int arg0, double arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateDouble(arg0, arg1);
+ }
+
+ public void updateFloat(int arg0, float arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateFloat(arg0, arg1);
+ }
+
+ public void updateInt(int arg0, int arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateInt(arg0, arg1);
+ }
+
+ public void updateLong(int arg0, long arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateLong(arg0, arg1);
+ }
+
+ public void updateNull(int arg0) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateNull(arg0);
+ }
+
+ public void updateNumericObject(int arg0, Object arg1, int arg2) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateNumericObject(arg0, arg1, arg2);
+ }
+
+ public void updateObject(int arg0, Object arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateObject(arg0, arg1);
+ }
+
+ public void updateShort(int arg0, short arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateShort(arg0, arg1);
+ }
+
+ public void updateString(int arg0, String arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateString(arg0, arg1);
+ }
+
+ public void updateTime(int arg0, Time arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateTime(arg0, arg1);
+ }
+
+ public void updateTimestamp(int arg0, DateTime arg1) throws SQLException {
+ checkDisposed();
+ implRowUpdate.updateTimestamp(arg0, arg1);
+ }
+
+ // XColumnLocate:
+
+ public int findColumn(String arg0) throws SQLException {
+ checkDisposed();
+ return implColumnLocate.findColumn(arg0);
+ }
+
+ // XPropertySet:
+
+ public void addPropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.addPropertyChangeListener(arg0, arg1);
+ }
+
+ public void addVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.addVetoableChangeListener(arg0, arg1);
+ }
+
+ public XPropertySetInfo getPropertySetInfo() {
+ checkDisposed();
+ return implPropertySet.getPropertySetInfo();
+ }
+
+ public Object getPropertyValue(String arg0) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ return implPropertySet.getPropertyValue(arg0);
+ }
+
+ public void removePropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.removePropertyChangeListener(arg0, arg1);
+ }
+
+ public void removeVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.removeVetoableChangeListener(arg0, arg1);
+ }
+
+ public void setPropertyValue(String arg0, Object arg1)
+ throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.setPropertyValue(arg0, arg1);
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlResultSetMetaData.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlResultSetMetaData.java
new file mode 100644
index 000000000000..cb54880787f6
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlResultSetMetaData.java
@@ -0,0 +1,127 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.sdbc.DataType;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XResultSetMetaData;
+
+public class PostgresqlResultSetMetaData extends WeakBase implements XResultSetMetaData {
+
+ private XResultSetMetaData impl;
+
+ public PostgresqlResultSetMetaData(XResultSetMetaData impl) {
+ this.impl = impl;
+ }
+
+ public String getCatalogName(int arg0) throws SQLException {
+ return impl.getCatalogName(arg0);
+ }
+
+ public int getColumnCount() throws SQLException {
+ return impl.getColumnCount();
+ }
+
+ public int getColumnDisplaySize(int arg0) throws SQLException {
+ return impl.getColumnDisplaySize(arg0);
+ }
+
+ public String getColumnLabel(int arg0) throws SQLException {
+ return impl.getColumnLabel(arg0);
+ }
+
+ public String getColumnName(int arg0) throws SQLException {
+ return impl.getColumnName(arg0);
+ }
+
+ public String getColumnServiceName(int arg0) throws SQLException {
+ return impl.getColumnServiceName(arg0);
+ }
+
+ public int getColumnType(int column) throws SQLException {
+ int columnType = impl.getColumnType(column);
+ if (columnType == DataType.BIT) {
+ String columnName = getColumnTypeName(column);
+ if (columnName.equals("bool")) {
+ columnType = DataType.BOOLEAN;
+ }
+ }
+ return columnType;
+ }
+
+ public String getColumnTypeName(int column) throws SQLException {
+ return impl.getColumnTypeName(column);
+ }
+
+ public int getPrecision(int arg0) throws SQLException {
+ return impl.getPrecision(arg0);
+ }
+
+ public int getScale(int arg0) throws SQLException {
+ return impl.getScale(arg0);
+ }
+
+ public String getSchemaName(int arg0) throws SQLException {
+ return impl.getSchemaName(arg0);
+ }
+
+ public String getTableName(int arg0) throws SQLException {
+ return impl.getTableName(arg0);
+ }
+
+ public boolean isAutoIncrement(int arg0) throws SQLException {
+ return impl.isAutoIncrement(arg0);
+ }
+
+ public boolean isCaseSensitive(int arg0) throws SQLException {
+ return impl.isCaseSensitive(arg0);
+ }
+
+ public boolean isCurrency(int arg0) throws SQLException {
+ return impl.isCurrency(arg0);
+ }
+
+ public boolean isDefinitelyWritable(int arg0) throws SQLException {
+ return impl.isDefinitelyWritable(arg0);
+ }
+
+ public int isNullable(int arg0) throws SQLException {
+ return impl.isNullable(arg0);
+ }
+
+ public boolean isReadOnly(int arg0) throws SQLException {
+ return impl.isReadOnly(arg0);
+ }
+
+ public boolean isSearchable(int arg0) throws SQLException {
+ return impl.isSearchable(arg0);
+ }
+
+ public boolean isSigned(int arg0) throws SQLException {
+ return impl.isSigned(arg0);
+ }
+
+ public boolean isWritable(int arg0) throws SQLException {
+ return impl.isWritable(arg0);
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlStatement.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlStatement.java
new file mode 100644
index 000000000000..462e10f23399
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlStatement.java
@@ -0,0 +1,188 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertyChangeListener;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+import com.sun.star.beans.XVetoableChangeListener;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lib.uno.helper.ComponentBase;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XCloseable;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbc.XMultipleResults;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XStatement;
+import com.sun.star.sdbc.XWarningsSupplier;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.util.XCancellable;
+
+public class PostgresqlStatement extends ComponentBase
+ implements XCloseable, XPropertySet, XCancellable, XStatement, XWarningsSupplier, XMultipleResults {
+
+ private XStatement impl;
+ private XCloseable implCloseable;
+ private XPropertySet implPropertySet;
+ private XCancellable implCancellable;
+ private XWarningsSupplier implWarningsSupplier;
+ private XMultipleResults implMultipleResults;
+ private XConnection connection;
+ private AtomicBoolean isDisposed = new AtomicBoolean(false);
+
+ public PostgresqlStatement(XStatement impl, XConnection connection) {
+ this.impl = impl;
+ this.implCloseable = UnoRuntime.queryInterface(XCloseable.class, impl);
+ this.implPropertySet = UnoRuntime.queryInterface(XPropertySet.class, impl);
+ this.implCancellable = UnoRuntime.queryInterface(XCancellable.class, impl);
+ this.implWarningsSupplier = UnoRuntime.queryInterface(XWarningsSupplier.class, impl);
+ this.implMultipleResults = UnoRuntime.queryInterface(XMultipleResults.class, impl);
+ this.connection = connection;
+ }
+
+ // XComponentBase:
+
+ @Override
+ protected void postDisposing() {
+ isDisposed.set(true);
+ try {
+ implCloseable.close();
+ } catch (SQLException sqlException) {
+ }
+ }
+
+ private void checkDisposed() throws DisposedException {
+ if (isDisposed.get()) {
+ throw new DisposedException();
+ }
+ }
+
+ // XStatement:
+
+ public boolean execute(String arg0) throws SQLException {
+ checkDisposed();
+ System.out.println(arg0);
+ return impl.execute(arg0);
+ }
+
+ public XResultSet executeQuery(String arg0) throws SQLException {
+ checkDisposed();
+ XResultSet results = impl.executeQuery(arg0);
+ return new PostgresqlResultSet(results, this);
+ }
+
+ public int executeUpdate(String arg0) throws SQLException {
+ checkDisposed();
+ return impl.executeUpdate(arg0);
+ }
+
+ public XConnection getConnection() throws SQLException {
+ checkDisposed();
+ return connection;
+ }
+
+ // XCloseable:
+
+ public void close() throws SQLException {
+ dispose();
+ }
+
+ // XPropertySet:
+
+ public void addPropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.addPropertyChangeListener(arg0, arg1);
+ }
+
+ public void addVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.addVetoableChangeListener(arg0, arg1);
+ }
+
+ public XPropertySetInfo getPropertySetInfo() {
+ checkDisposed();
+ return implPropertySet.getPropertySetInfo();
+ }
+
+ public Object getPropertyValue(String arg0) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ return implPropertySet.getPropertyValue(arg0);
+ }
+
+ public void removePropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.removePropertyChangeListener(arg0, arg1);
+ }
+
+ public void removeVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.removeVetoableChangeListener(arg0, arg1);
+ }
+
+ public void setPropertyValue(String arg0, Object arg1)
+ throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.setPropertyValue(arg0, arg1);
+ }
+
+ // XCancellable:
+
+ public void cancel() {
+ checkDisposed();
+ implCancellable.cancel();
+ }
+
+ // XWarningsSupplier:
+
+ public void clearWarnings() throws SQLException {
+ checkDisposed();
+ implWarningsSupplier.clearWarnings();
+ }
+
+ public Object getWarnings() throws SQLException {
+ checkDisposed();
+ return implWarningsSupplier.getWarnings();
+ }
+
+ // XMultipleResults:
+
+ public boolean getMoreResults() throws SQLException {
+ checkDisposed();
+ return implMultipleResults.getMoreResults();
+ }
+
+ public XResultSet getResultSet() throws SQLException {
+ checkDisposed();
+ return new PostgresqlResultSet(implMultipleResults.getResultSet(), this);
+ }
+
+ public int getUpdateCount() throws SQLException {
+ checkDisposed();
+ return implMultipleResults.getUpdateCount();
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlTable.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlTable.java
new file mode 100644
index 000000000000..426bded92625
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlTable.java
@@ -0,0 +1,125 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import java.util.List;
+import java.util.Map;
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.ElementExistException;
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.lang.IndexOutOfBoundsException;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OColumnContainer;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OContainer;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OIndexContainer;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OKey;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OKeyContainer;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OTable;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.SqlTableHelper;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.SqlTableHelper.ColumnDescription;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxTableDescriptor;
+
+public class PostgresqlTable extends OTable {
+ private PostgresqlTable(Object lock, XConnection connection, OContainer tables, String name,
+ String catalogName, String schemaName, String description, String type) {
+ super(lock, name, true, connection, tables);
+ super.catalogName = catalogName;
+ super.schemaName = schemaName;
+ super.description = description;
+ super.type = type;
+ }
+
+ public static PostgresqlTable create(XConnection connection, OContainer tables, String name,
+ String catalogName, String schemaName, String description, String type) {
+ Object lock = new Object();
+ return new PostgresqlTable(lock, connection, tables, name, catalogName, schemaName, description, type);
+ }
+
+ @Override
+ public XPropertySet createDataDescriptor() {
+ SdbcxTableDescriptor descriptor = SdbcxTableDescriptor.create(true);
+ synchronized (lock) {
+ CompHelper.copyProperties(this, descriptor);
+ }
+ return descriptor;
+ }
+
+ @Override
+ public void setName(String name) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void rename(String name) throws SQLException, ElementExistException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void alterColumnByIndex(int index, XPropertySet descriptor) throws SQLException, IndexOutOfBoundsException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void alterColumnByName(String name, XPropertySet descriptor) throws SQLException, NoSuchElementException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected OContainer refreshColumns() {
+ try {
+ List<ColumnDescription> columns = new SqlTableHelper().readColumns(getConnection().getMetaData(), catalogName, schemaName, getName());
+ return new OColumnContainer(lock, isCaseSensitive(), columns, this, getConnection().getMetaData());
+ } catch (SQLException sqlException) {
+ return null;
+ }
+ }
+
+ @Override
+ protected OContainer refreshIndexes() {
+ try {
+ List<String> indexes = new SqlTableHelper().readIndexes(getConnection().getMetaData(), catalogName, schemaName, getName(), this);
+ return new OIndexContainer(lock, indexes, isCaseSensitive(), this);
+ } catch (SQLException sqlException) {
+ return null;
+ }
+ }
+
+ @Override
+ protected OContainer refreshKeys() {
+ try {
+ Map<String, OKey> keys = new SqlTableHelper().readKeys(
+ getConnection().getMetaData(), catalogName, schemaName, getName(), isCaseSensitive(), this);
+ return OKeyContainer.create(isCaseSensitive(), keys, this);
+ } catch (SQLException sqlException) {
+ return null;
+ }
+ }
+
+
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlTables.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlTables.java
new file mode 100644
index 000000000000..7591f7974153
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/PostgresqlTables.java
@@ -0,0 +1,151 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql;
+
+import java.util.List;
+
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.IndexOutOfBoundsException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XDatabaseMetaData;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbc.XStatement;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OContainer;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxTableDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.ComposeRule;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools.NameComponents;
+import com.sun.star.uno.Any;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+
+public class PostgresqlTables extends OContainer {
+ private XDatabaseMetaData metadata;
+ private PostgresqlCatalog catalog;
+
+ public PostgresqlTables(Object lock, XDatabaseMetaData metadata, PostgresqlCatalog catalog, List<String> names) {
+ super(lock, true, names);
+ this.metadata = metadata;
+ this.catalog = catalog;
+ }
+
+ @Override
+ public XPropertySet createObject(String name) throws SQLException {
+ NameComponents nameComponents = DbTools.qualifiedNameComponents(metadata, name, ComposeRule.InDataManipulation);
+ Object queryCatalog = nameComponents.getCatalog().isEmpty() ? Any.VOID : nameComponents.getCatalog();
+ XPropertySet ret = null;
+ XResultSet results = null;
+ try {
+ results = metadata.getTables(
+ queryCatalog, nameComponents.getSchema(), nameComponents.getTable(), new String[] { "VIEW", "TABLE", "%" });
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ if (results.next()) {
+ String type = row.getString(4);
+ String remarks = row.getString(5);
+ ret = PostgresqlTable.create(metadata.getConnection(), this, nameComponents.getTable(),
+ nameComponents.getCatalog(), nameComponents.getSchema(), remarks, type);
+ }
+ }
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+ return ret;
+
+ }
+
+ @Override
+ public void dropObject(int index, String name) throws SQLException {
+ try {
+ Object object = getObject(index);
+
+ NameComponents nameComponents = DbTools.qualifiedNameComponents(metadata, name, ComposeRule.InDataManipulation);
+
+ boolean isView = false;
+ XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, object);
+ if (propertySet != null) {
+ isView = AnyConverter.toString(propertySet.getPropertyValue(PropertyIds.TYPE.name)).equals("VIEW");
+ }
+
+ String composedName = DbTools.composeTableName(metadata, nameComponents.getCatalog(), nameComponents.getSchema(), nameComponents.getTable(),
+ true, ComposeRule.InDataManipulation);
+ String sql = String.format("DROP %s %s", isView ? "VIEW" : "TABLE", composedName);
+
+ XStatement statement = null;
+ try {
+ statement = metadata.getConnection().createStatement();
+ statement.execute(sql);
+ } finally {
+ CompHelper.disposeComponent(statement);
+ }
+ // FIXME: delete it from our views
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, illegalArgumentException);
+ } catch (UnknownPropertyException unknownPropertyException) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, unknownPropertyException);
+ } catch (WrappedTargetException wrappedTargetException) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, wrappedTargetException);
+ }
+ }
+
+ @Override
+ public void impl_refresh() {
+ catalog.refreshTables();
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxTableDescriptor.create(true);
+ }
+
+ @Override
+ public XPropertySet appendObject(String name, XPropertySet descriptor) throws SQLException {
+ createTable(descriptor);
+ return createObject(name);
+ }
+
+ void createTable(XPropertySet descriptor) throws SQLException {
+ XStatement statement = null;
+ try {
+ String sql = DbTools.createSqlCreateTableStatement(descriptor, metadata.getConnection(), null, "(M,D)");
+ statement = metadata.getConnection().createStatement();
+ statement.execute(sql);
+ } catch (IndexOutOfBoundsException indexOutOfBoundsException) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, indexOutOfBoundsException);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, illegalArgumentException);
+ } catch (UnknownPropertyException unknownPropertyException) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, unknownPropertyException);
+ } catch (WrappedTargetException wrappedTargetException) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, wrappedTargetException);
+ } finally {
+ CompHelper.disposeComponent(statement);
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/CompHelper.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/CompHelper.java
new file mode 100644
index 000000000000..27ac3439e2ba
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/CompHelper.java
@@ -0,0 +1,74 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.comphelper;
+
+import com.sun.star.beans.Property;
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.uno.UnoRuntime;
+
+public class CompHelper {
+ /**
+ * If the given parameter is an XComponent, calls dispose() on it.
+ * @param object the UNO interface to try dispose; may be null.
+ */
+ public static void disposeComponent(final Object object) {
+ final XComponent component = UnoRuntime.queryInterface(XComponent.class, object);
+ if (component != null) {
+ component.dispose();
+ }
+ }
+
+ public static void copyProperties(final XPropertySet src, final XPropertySet dst) {
+ if (src == null || dst == null) {
+ return;
+ }
+
+ XPropertySetInfo srcPropertySetInfo = src.getPropertySetInfo();
+ XPropertySetInfo dstPropertySetInfo = dst.getPropertySetInfo();
+
+ for (Property srcProperty : srcPropertySetInfo.getProperties()) {
+ if (dstPropertySetInfo.hasPropertyByName(srcProperty.Name)) {
+ try {
+ Property dstProperty = dstPropertySetInfo.getPropertyByName(srcProperty.Name);
+ if ((dstProperty.Attributes & PropertyAttribute.READONLY) == 0) {
+ Object value = src.getPropertyValue(srcProperty.Name);
+ if ((dstProperty.Attributes & PropertyAttribute.MAYBEVOID) == 0 || value != null) {
+ dst.setPropertyValue(srcProperty.Name, value);
+ }
+ }
+ } catch (Exception e) {
+ String error = "Could not copy property '" + srcProperty.Name +
+ "' to the destination set";
+ XServiceInfo serviceInfo = UnoRuntime.queryInterface(XServiceInfo.class, dst);
+ if (serviceInfo != null) {
+ error += " (a '" + serviceInfo.getImplementationName() + "' implementation)";
+ }
+
+ }
+ }
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OArrayEnumeration.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OArrayEnumeration.java
new file mode 100644
index 000000000000..aa24b3154bee
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OArrayEnumeration.java
@@ -0,0 +1,55 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.comphelper;
+
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.container.XEnumeration;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lib.uno.helper.WeakBase;
+
+public class OArrayEnumeration extends WeakBase implements XEnumeration {
+ private Object[] elements;
+ private int position;
+
+ public OArrayEnumeration(Object[] elements) {
+ this.elements = elements;
+ }
+
+ @Override
+ public boolean hasMoreElements() {
+ synchronized (this) {
+ return position < elements.length;
+ }
+ }
+
+ @Override
+ public Object nextElement()
+ throws NoSuchElementException, WrappedTargetException {
+ synchronized (this) {
+ if (position < elements.length) {
+ return elements[position++];
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OEnumerationByIndex.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OEnumerationByIndex.java
new file mode 100644
index 000000000000..5af79235e4b0
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OEnumerationByIndex.java
@@ -0,0 +1,118 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.comphelper;
+
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.container.XEnumeration;
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XEventListener;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+
+public class OEnumerationByIndex extends WeakBase implements XEnumeration, XEventListener {
+ private XIndexAccess collection;
+ private int position;
+ boolean isListening;
+
+ public OEnumerationByIndex(XIndexAccess collection) {
+ this.collection = collection;
+ startDisposeListening();
+ }
+
+ @Override
+ public void disposing(EventObject event) {
+ synchronized (this) {
+ if (event.Source == collection) {
+ collection = null;
+ }
+ }
+ }
+
+ @Override
+ public boolean hasMoreElements() {
+ synchronized (this) {
+ if (collection != null) {
+ if (position < collection.getCount()) {
+ return true;
+ } else {
+ stopDisposeListening();
+ collection = null;
+ }
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public Object nextElement()
+ throws NoSuchElementException, WrappedTargetException {
+ Object value = null;
+ synchronized (this) {
+ if (collection != null) {
+ if (position < collection.getCount()) {
+ try {
+ value = collection.getByIndex(position++);
+ } catch (com.sun.star.lang.IndexOutOfBoundsException indexOutOfBoundsException) {
+ // can't happen
+ }
+ }
+ if (position >= collection.getCount()) {
+ stopDisposeListening();
+ collection = null;
+ }
+ }
+ }
+ if (value == null) {
+ throw new NoSuchElementException();
+ }
+ return value;
+ }
+
+ private void startDisposeListening() {
+ synchronized (this) {
+ if (isListening) {
+ return;
+ }
+ XComponent component = UnoRuntime.queryInterface(XComponent.class, collection);
+ if (component != null) {
+ component.addEventListener(this);
+ isListening = true;
+ }
+ }
+ }
+
+ private void stopDisposeListening() {
+ synchronized (this) {
+ if (!isListening) {
+ return;
+ }
+ XComponent component = UnoRuntime.queryInterface(XComponent.class, collection);
+ if (component != null) {
+ component.removeEventListener(this);
+ isListening = false;
+ }
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OEnumerationByName.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OEnumerationByName.java
new file mode 100644
index 000000000000..155c8e5227e8
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/OEnumerationByName.java
@@ -0,0 +1,116 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.comphelper;
+
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.container.XEnumeration;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XEventListener;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+
+public class OEnumerationByName extends WeakBase implements XEnumeration, XEventListener {
+ private String[] names;
+ private int position;
+ private XNameAccess collection;
+ private boolean isListening;
+
+ public OEnumerationByName(XNameAccess collection) {
+ this.collection = collection;
+ names = collection.getElementNames();
+ startDisposeListening();
+ }
+
+ @Override
+ public void disposing(EventObject event) {
+ synchronized (this) {
+ if (event.Source == collection) {
+ collection = null;
+ }
+ }
+ }
+
+ @Override
+ public boolean hasMoreElements() {
+ synchronized (this) {
+ if (collection != null) {
+ if (position < names.length) {
+ return true;
+ } else {
+ stopDisposeListening();
+ collection = null;
+ }
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public Object nextElement()
+ throws NoSuchElementException, WrappedTargetException {
+ Object value = null;
+ synchronized (this) {
+ if (collection != null) {
+ if (position < names.length) {
+ value = collection.getByName(names[position++]);
+ }
+ if (position >= names.length) {
+ stopDisposeListening();
+ collection = null;
+ }
+ }
+ }
+ if (value == null) {
+ throw new NoSuchElementException();
+ }
+ return value;
+ }
+
+ private void startDisposeListening() {
+ synchronized (this) {
+ if (isListening) {
+ return;
+ }
+ XComponent component = UnoRuntime.queryInterface(XComponent.class, collection);
+ if (component != null) {
+ component.addEventListener(this);
+ isListening = true;
+ }
+ }
+ }
+
+ private void stopDisposeListening() {
+ synchronized (this) {
+ if (!isListening) {
+ return;
+ }
+ XComponent component = UnoRuntime.queryInterface(XComponent.class, collection);
+ if (component != null) {
+ component.removeEventListener(this);
+ isListening = false;
+ }
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/PropertySet.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/PropertySet.java
new file mode 100644
index 000000000000..a49a2dd6b4e5
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/PropertySet.java
@@ -0,0 +1,160 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.comphelper;
+
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XFastPropertySet;
+import com.sun.star.beans.XMultiPropertySet;
+import com.sun.star.beans.XPropertiesChangeListener;
+import com.sun.star.beans.XPropertyChangeListener;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+import com.sun.star.beans.XVetoableChangeListener;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lib.uno.helper.ComponentBase;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertySetter;
+import com.sun.star.uno.Type;
+
+public class PropertySet extends ComponentBase implements XPropertySet, XFastPropertySet, XMultiPropertySet {
+ private final PropertySetAdapter impl;
+
+ protected PropertySet(Object lock) {
+ impl = new PropertySetAdapter(lock, this);
+ }
+
+ @Override
+ protected void postDisposing() {
+ impl.dispose();
+ }
+
+ public void registerProperty(String propertyName, int handle, Type type, short attributes, PropertyGetter getter, PropertySetter setter) {
+ impl.registerProperty(propertyName, handle, type, attributes, getter, setter);
+ }
+
+ public void registerProperty(String propertyName, Type type, short attributes, PropertyGetter getter, PropertySetter setter) {
+ impl.registerProperty(propertyName, type, attributes, getter, setter);
+ }
+
+ public void addPropertyChangeListener(String propertyName, XPropertyChangeListener listener) throws UnknownPropertyException, WrappedTargetException {
+ // only add listeners if you are not disposed
+ if (!bInDispose && !bDisposed) {
+ impl.addPropertyChangeListener(propertyName, listener);
+ }
+ }
+
+ public void addVetoableChangeListener(String propertyName, XVetoableChangeListener listener) throws UnknownPropertyException, WrappedTargetException {
+ // only add listeners if you are not disposed
+ if (!bInDispose && !bDisposed) {
+ impl.addVetoableChangeListener(propertyName, listener);
+ }
+ }
+
+ public void addPropertiesChangeListener(String[] propertyNames, XPropertiesChangeListener listener) {
+ // only add listeners if you are not disposed
+ if (!bInDispose && !bDisposed) {
+ impl.addPropertiesChangeListener(propertyNames, listener);
+ }
+ }
+
+ public XPropertySetInfo getPropertySetInfo() {
+ return impl.getPropertySetInfo();
+ }
+
+ public Object getPropertyValue(String propertyName) throws UnknownPropertyException, WrappedTargetException {
+ if (bInDispose || bDisposed) {
+ throw new DisposedException("Component is already disposed");
+ }
+ return impl.getPropertyValue(propertyName);
+ }
+
+ @Override
+ public Object getFastPropertyValue(int handle) throws UnknownPropertyException, WrappedTargetException {
+ if (bInDispose || bDisposed) {
+ throw new DisposedException("Component is already disposed");
+ }
+ return impl.getFastPropertyValue(handle);
+ }
+
+ public Object[] getPropertyValues(String[] propertyNames) {
+ if (bInDispose || bDisposed) {
+ throw new DisposedException("Component is already disposed");
+ }
+ return impl.getPropertyValues(propertyNames);
+ }
+
+ public void removePropertyChangeListener(String propertyName, XPropertyChangeListener listener) throws UnknownPropertyException, WrappedTargetException {
+ // all listeners are automatically released in a dispose call
+ if (!bInDispose && !bDisposed) {
+ impl.removePropertyChangeListener(propertyName, listener);
+ }
+ }
+
+ public void removeVetoableChangeListener(String propertyName, XVetoableChangeListener listener) throws UnknownPropertyException, WrappedTargetException {
+ // all listeners are automatically released in a dispose call
+ if (!bInDispose && !bDisposed) {
+ impl.removeVetoableChangeListener(propertyName, listener);
+ }
+ }
+
+ public void removePropertiesChangeListener(XPropertiesChangeListener listener) {
+ // all listeners are automatically released in a dispose call
+ if (!bInDispose && !bDisposed) {
+ impl.removePropertiesChangeListener(listener);
+ }
+ }
+
+ public void setPropertyValue(String propertyName, Object value)
+ throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ if (bInDispose || bDisposed) {
+ throw new DisposedException("Component is already disposed");
+ }
+ impl.setPropertyValue(propertyName, value);
+ }
+
+ public void setFastPropertyValue(int handle, Object value)
+ throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ if (bInDispose || bDisposed) {
+ throw new DisposedException("Component is already disposed");
+ }
+ impl.setFastPropertyValue(handle, value);
+ }
+
+ public void setPropertyValues(String[] propertyNames, Object[] values) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ if (bInDispose || bDisposed) {
+ throw new DisposedException("Component is already disposed");
+ }
+ impl.setPropertyValues(propertyNames, values);
+ }
+
+ public void firePropertiesChangeEvent(String[] propertyNames, XPropertiesChangeListener listener) {
+ if (bInDispose || bDisposed) {
+ throw new DisposedException("Component is already disposed");
+ }
+ impl.firePropertiesChangeEvent(propertyNames, listener);
+ }
+
+
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/PropertySetAdapter.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/PropertySetAdapter.java
new file mode 100644
index 000000000000..03de4f065cc4
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/comphelper/PropertySetAdapter.java
@@ -0,0 +1,411 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.comphelper;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.sun.star.beans.Property;
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.beans.PropertyChangeEvent;
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XFastPropertySet;
+import com.sun.star.beans.XMultiPropertySet;
+import com.sun.star.beans.XPropertiesChangeListener;
+import com.sun.star.beans.XPropertyChangeListener;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+import com.sun.star.beans.XVetoableChangeListener;
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lib.uno.helper.InterfaceContainer;
+import com.sun.star.lib.uno.helper.MultiTypeInterfaceContainer;
+import com.sun.star.uno.Any;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.Type;
+import com.sun.star.uno.TypeClass;
+import com.sun.star.uno.XInterface;
+
+public class PropertySetAdapter implements XPropertySet, XFastPropertySet, XMultiPropertySet {
+ private final Object lock;
+ private final Object eventSource;
+ // after registerListeners(), these are read-only:
+ private final Map<String,PropertyData> propertiesByName = new HashMap<String,PropertyData>();
+ private final Map<Integer,PropertyData> propertiesByHandle = new HashMap<Integer,PropertyData>();
+ private int nextHandle = 1;
+ // interface containers are locked internally:
+ protected final MultiTypeInterfaceContainer boundListeners = new MultiTypeInterfaceContainer();
+ protected final MultiTypeInterfaceContainer vetoableListeners = new MultiTypeInterfaceContainer();
+ protected final InterfaceContainer propertiesChangeListeners = new InterfaceContainer();
+ private final PropertySetInfo propertySetInfo = new PropertySetInfo();
+
+ public static interface PropertyGetter {
+ Object getValue();
+ }
+
+ public static interface PropertySetter {
+ void setValue(Object value);
+ }
+
+ private static class PropertyData {
+ Property property;
+ PropertyGetter getter;
+ PropertySetter setter;
+
+ PropertyData(Property property, PropertyGetter getter, PropertySetter setter) {
+ this.property = property;
+ this.getter = getter;
+ this.setter = setter;
+ }
+ }
+
+ private static final Comparator<Property> propertyNameComparator = new Comparator<Property>() {
+ @Override
+ public int compare(Property first, Property second) {
+ return first.Name.compareTo(second.Name);
+ }
+ };
+
+ private class PropertySetInfo implements XPropertySetInfo {
+ @Override
+ public Property[] getProperties() {
+ Property[] properties = new Property[propertiesByName.size()];
+ int next = 0;
+ for (Map.Entry<String,PropertyData> entry : propertiesByName.entrySet()) {
+ properties[next++] = entry.getValue().property;
+ }
+ Arrays.sort(properties, propertyNameComparator);
+ return properties;
+ }
+
+ @Override
+ public Property getPropertyByName(String propertyName) throws UnknownPropertyException {
+ PropertyData propertyData = getPropertyData(propertyName);
+ return propertyData.property;
+ }
+
+ @Override
+ public boolean hasPropertyByName(String propertyName) {
+ return propertiesByName.containsKey(propertyName);
+ }
+ }
+
+ /**
+ * Creates a new instance.
+ * @param lock the lock that will be held while calling the getters and setters
+ * @param eventSource the com.sun.star.lang.EventObject Source field, to use in events sent to listeners
+ */
+ public PropertySetAdapter(Object lock, Object eventSource) {
+ this.lock = lock;
+ this.eventSource = eventSource;
+ }
+
+ public void dispose() {
+ // Create an event with this as sender
+ EventObject event = new EventObject(eventSource);
+
+ // inform all listeners to release this object
+ boundListeners.disposeAndClear(event);
+ vetoableListeners.disposeAndClear(event);
+ }
+
+ public void registerProperty(String propertyName, int handle, Type type, short attributes,
+ PropertyGetter getter, PropertySetter setter) {
+ Property property = new Property(propertyName, handle, type, attributes);
+ PropertyData propertyData = new PropertyData(property, getter, setter);
+ propertiesByName.put(propertyName, propertyData);
+ propertiesByHandle.put(property.Handle, propertyData);
+ }
+
+ public void registerProperty(String propertyName, Type type, short attributes,
+ PropertyGetter getter, PropertySetter setter) {
+ int handle;
+ // registerProperty() should only be called from one thread, but just in case:
+ synchronized (lock) {
+ handle = nextHandle++;
+ }
+ registerProperty(propertyName, handle, type, attributes, getter, setter);
+ }
+
+ @Override
+ public void addPropertyChangeListener(
+ String propertyName, XPropertyChangeListener listener) throws UnknownPropertyException, WrappedTargetException {
+ PropertyData propertyData = getPropertyData(propertyName);
+ if ((propertyData.property.Attributes & PropertyAttribute.BOUND) != 0) {
+ boundListeners.addInterface(propertyName, listener);
+ } // else ignore silently
+ }
+
+ @Override
+ public void addVetoableChangeListener(
+ String propertyName, XVetoableChangeListener listener) throws UnknownPropertyException, WrappedTargetException {
+ PropertyData propertyData = getPropertyData(propertyName);
+ if ((propertyData.property.Attributes & PropertyAttribute.CONSTRAINED) != 0) {
+ vetoableListeners.addInterface(propertyName, listener);
+ } // else ignore silently
+ }
+
+ @Override
+ public void addPropertiesChangeListener(String[] propertyNames, XPropertiesChangeListener listener) {
+ propertiesChangeListeners.add(listener);
+ }
+
+ @Override
+ public XPropertySetInfo getPropertySetInfo() {
+ return propertySetInfo;
+ }
+
+ private PropertyData getPropertyData(String propertyName) throws UnknownPropertyException {
+ PropertyData propertyData = propertiesByName.get(propertyName);
+ if (propertyData == null) {
+ throw new UnknownPropertyException(propertyName);
+ }
+ return propertyData;
+ }
+
+ private PropertyData getPropertyData(int handle) throws UnknownPropertyException {
+ PropertyData propertyData = propertiesByHandle.get(handle);
+ if (propertyData == null) {
+ throw new UnknownPropertyException(Integer.toString(handle));
+ }
+ return propertyData;
+ }
+
+ private Object getPropertyValue(PropertyData propertyData) {
+ Object ret;
+ synchronized (lock) {
+ ret = propertyData.getter.getValue();
+ }
+
+ // null must not be returned. Either a void any is returned or an any containing
+ // an interface type and a null reference.
+ if (ret == null) {
+ if (propertyData.property.Type.getTypeClass() == TypeClass.INTERFACE) {
+ ret = new Any(propertyData.property.Type, null);
+ } else {
+ ret = new Any(new Type(void.class), null);
+ }
+ }
+ return ret;
+ }
+
+ @Override
+ public Object getPropertyValue(String propertyName) throws UnknownPropertyException, WrappedTargetException {
+ PropertyData propertyData = getPropertyData(propertyName);
+ return getPropertyValue(propertyData);
+ }
+
+ @Override
+ public Object getFastPropertyValue(int handle) throws UnknownPropertyException, WrappedTargetException {
+ PropertyData propertyData = getPropertyData(handle);
+ return getPropertyValue(propertyData);
+ }
+
+ @Override
+ public Object[] getPropertyValues(String[] propertyNames) {
+ Object[] values = new Object[propertyNames.length];
+ for (int i = 0; i < propertyNames.length; i++) {
+ Object value = null;
+ try {
+ value = getPropertyValue(propertyNames[i]);
+ } catch (UnknownPropertyException unknownPropertyException) {
+ } catch (WrappedTargetException wrappedTargetException) {
+ }
+ values[i] = value;
+ }
+ return values;
+ }
+
+ @Override
+ public void removePropertyChangeListener(
+ String propertyName, XPropertyChangeListener listener) throws UnknownPropertyException, WrappedTargetException {
+ // check existence:
+ getPropertyData(propertyName);
+ boundListeners.removeInterface(propertyName, listener);
+ }
+
+ @Override
+ public synchronized void removeVetoableChangeListener(
+ String propertyName, XVetoableChangeListener listener) throws UnknownPropertyException, WrappedTargetException {
+ // check existence:
+ getPropertyData(propertyName);
+ vetoableListeners.removeInterface(propertyName, listener);
+ }
+
+ @Override
+ public void removePropertiesChangeListener(XPropertiesChangeListener listener) {
+ propertiesChangeListeners.remove(listener);
+ }
+
+ @Override
+ public void setPropertyValue(String propertyName, Object value)
+ throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ PropertyData propertyData = getPropertyData(propertyName);
+ setPropertyValue(propertyData, value);
+ }
+
+ @Override
+ public void setFastPropertyValue(int handle, Object value)
+ throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ PropertyData propertyData = getPropertyData(handle);
+ setPropertyValue(propertyData, value);
+ }
+
+ private void setPropertyValue(PropertyData propertyData, Object value)
+ throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ if ((propertyData.property.Attributes & PropertyAttribute.READONLY) != 0) {
+ throw new PropertyVetoException();
+ }
+ // The value may be null only if MAYBEVOID attribute is set
+ boolean isVoid = false;
+ if (value instanceof Any) {
+ isVoid = ((Any) value).getObject() == null;
+ } else {
+ isVoid = value == null;
+ }
+ if (isVoid && (propertyData.property.Attributes & PropertyAttribute.MAYBEVOID) == 0) {
+ throw new IllegalArgumentException("The property must have a value; the MAYBEVOID attribute is not set!");
+ }
+
+ // Check if the argument is allowed
+ boolean isValueOk = false;
+ if (value instanceof Any) {
+ isValueOk = checkType(((Any) value).getObject());
+ } else {
+ isValueOk = checkType(value);
+ }
+ if (!isValueOk) {
+ throw new IllegalArgumentException("No valid UNO type");
+ }
+
+ Object[] futureValue = new Object[] { AnyConverter.toObject(propertyData.property.Type, value) };
+ Object[] currentValue = new Object[] { getPropertyValue(propertyData.property.Name) };
+ Property[] properties = new Property[] { propertyData.property };
+
+ fire(properties, currentValue, futureValue, false);
+ synchronized (lock) {
+ propertyData.setter.setValue(futureValue[0]);
+ }
+ fire(properties, currentValue, futureValue, true);
+ }
+
+ @Override
+ public void setPropertyValues(String[] propertyNames, Object[] values) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ for (int i = 0; i < propertyNames.length; i++) {
+ try {
+ setPropertyValue(propertyNames[i], values[i]);
+ } catch (UnknownPropertyException e) {
+ continue;
+ }
+ }
+ }
+
+ private boolean checkType(Object obj) {
+ if (obj == null
+ || obj instanceof Boolean
+ || obj instanceof Character
+ || obj instanceof Number
+ || obj instanceof String
+ || obj instanceof XInterface
+ || obj instanceof Type
+ || obj instanceof com.sun.star.uno.Enum
+ || obj.getClass().isArray())
+ return true;
+ return false;
+ }
+
+ @Override
+ public void firePropertiesChangeEvent(String[] propertyNames, XPropertiesChangeListener listener) {
+ PropertyChangeEvent[] events = new PropertyChangeEvent[propertyNames.length];
+ int eventCount = 0;
+ for (int i = 0; i < propertyNames.length; i++) {
+ try {
+ PropertyData propertyData = getPropertyData(propertyNames[i]);
+ Object value = getPropertyValue(propertyNames[i]);
+ events[eventCount++] = new PropertyChangeEvent(eventSource, propertyNames[i],
+ false, propertyData.property.Handle, value, value);
+ } catch (UnknownPropertyException unknownPropertyException) {
+ } catch (WrappedTargetException wrappedTargetException) {
+ }
+ }
+ if (eventCount > 0) {
+ if (events.length != eventCount) {
+ PropertyChangeEvent[] tmp = new PropertyChangeEvent[eventCount];
+ System.arraycopy(events, 0, tmp, 0, eventCount);
+ events = tmp;
+ }
+ listener.propertiesChange(events);
+ }
+ }
+
+ private void fire(Property[] properties, Object[] oldValues, Object[] newValues, boolean hasChanged) throws PropertyVetoException {
+ PropertyChangeEvent[] events = new PropertyChangeEvent[properties.length];
+ int eventCount = 0;
+ for (int i = 0; i < properties.length; i++) {
+ if ((!hasChanged && (properties[i].Attributes & PropertyAttribute.CONSTRAINED) != 0) ||
+ (hasChanged && (properties[i].Attributes & PropertyAttribute.BOUND) != 0)) {
+ events[eventCount++] = new PropertyChangeEvent(
+ eventSource, properties[i].Name, false, properties[i].Handle, oldValues[i], newValues[i]);
+ }
+ }
+ for (int i = 0; i < eventCount; i++) {
+ fireListeners(hasChanged, events[i].PropertyName, events[i]);
+ fireListeners(hasChanged, "", events[i]);
+ }
+ if (hasChanged && eventCount > 0) {
+ if (eventCount != events.length) {
+ PropertyChangeEvent[] tmp = new PropertyChangeEvent[eventCount];
+ System.arraycopy(events, 0, tmp, 0, eventCount);
+ events = tmp;
+ }
+ for (Iterator<?> it = propertiesChangeListeners.iterator(); it.hasNext();) {
+ XPropertiesChangeListener listener = (XPropertiesChangeListener) it.next();
+ listener.propertiesChange(events);
+ }
+ }
+ }
+
+ private void fireListeners(boolean hasChanged, String key, PropertyChangeEvent event) throws PropertyVetoException {
+ InterfaceContainer listeners;
+ if (hasChanged) {
+ listeners = boundListeners.getContainer(key);
+ } else {
+ listeners = vetoableListeners.getContainer(key);
+ }
+ if (listeners != null) {
+ Iterator<?> it = listeners.iterator();
+ while (it.hasNext()) {
+ Object listener = it.next();
+ if (hasChanged) {
+ ((XPropertyChangeListener)listener).propertyChange(event);
+ } else {
+ ((XVetoableChangeListener)listener).vetoableChange(event);
+ }
+ }
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/ISQLStatementHelper.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/ISQLStatementHelper.java
new file mode 100644
index 000000000000..52fbf7f466ca
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/ISQLStatementHelper.java
@@ -0,0 +1,28 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import com.sun.star.beans.XPropertySet;
+
+public interface ISQLStatementHelper {
+ void addComment(XPropertySet propertySet, StringBuilder sql);
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OCatalog.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OCatalog.java
new file mode 100644
index 000000000000..aba5c1fb3d0b
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OCatalog.java
@@ -0,0 +1,169 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import com.sun.star.container.XNameAccess;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lib.uno.helper.ComponentBase;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XDatabaseMetaData;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbcx.XGroupsSupplier;
+import com.sun.star.sdbcx.XTablesSupplier;
+import com.sun.star.sdbcx.XUsersSupplier;
+import com.sun.star.sdbcx.XViewsSupplier;
+import com.sun.star.sdbcx.comp.postgresql.util.ComposeRule;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+
+public abstract class OCatalog extends ComponentBase
+ implements XTablesSupplier, XViewsSupplier, XUsersSupplier, XGroupsSupplier, XServiceInfo {
+
+ private static final String[] services = {
+ "com.sun.star.sdbcx.DatabaseDefinition"
+ };
+
+ protected final Object lock = new Object();
+ // Deleted on destruction, weakly held by caller:
+ protected OContainer tables;
+ protected OContainer views;
+ protected OContainer groups;
+ protected OContainer users;
+ protected XDatabaseMetaData metadata;
+
+ public OCatalog(XDatabaseMetaData metadata) {
+ this.metadata = metadata;
+ }
+
+ private void checkDisposed() throws DisposedException {
+ if (bInDispose || bDisposed) {
+ throw new DisposedException();
+ }
+ }
+
+ @Override
+ protected void postDisposing() {
+ synchronized (lock) {
+ if (tables != null) {
+ tables.dispose();
+ }
+ if (views != null) {
+ views.dispose();
+ }
+ if (groups != null) {
+ groups.dispose();
+ }
+ if (users != null) {
+ users.dispose();
+ }
+ }
+ }
+
+ // XServiceInfo
+
+ @Override
+ public String getImplementationName() {
+ return "com.sun.star.comp.connectivity.OCatalog";
+ }
+
+ @Override
+ public String[] getSupportedServiceNames() {
+ return services.clone();
+ }
+
+ @Override
+ public boolean supportsService(String serviceName) {
+ for (String service : getSupportedServiceNames()) {
+ if (service.equals(serviceName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // X(Tables/Views/Groups/Users)Supplier
+
+ @Override
+ public XNameAccess getTables() {
+ checkDisposed();
+ synchronized (lock) {
+ if (tables == null) {
+ tables = refreshTables();
+ }
+ return tables;
+ }
+ }
+
+ @Override
+ public XNameAccess getViews() {
+ checkDisposed();
+ synchronized (lock) {
+ if (views == null) {
+ views = refreshViews();
+ }
+ return views;
+ }
+ }
+
+ @Override
+ public XNameAccess getGroups() {
+ checkDisposed();
+ synchronized (lock) {
+ if (groups == null) {
+ groups = refreshGroups();
+ }
+ return groups;
+ }
+ }
+
+ @Override
+ public XNameAccess getUsers() {
+ checkDisposed();
+ synchronized (lock) {
+ if (users == null) {
+ users = refreshUsers();
+ }
+ return users;
+ }
+ }
+
+ protected String buildName(XRow row) throws SQLException {
+ String catalog = row.getString(1);
+ if (row.wasNull()) {
+ catalog = "";
+ }
+ String schema = row.getString(2);
+ if (row.wasNull()) {
+ schema = null;
+ }
+ String table = row.getString(3);
+ if (row.wasNull()) {
+ table = "";
+ }
+ return DbTools.composeTableName(metadata, catalog, schema, table, false, ComposeRule.InDataManipulation);
+ }
+
+ public abstract OContainer refreshTables();
+ public abstract OContainer refreshViews();
+ public abstract OContainer refreshGroups();
+ public abstract OContainer refreshUsers();
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OColumn.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OColumn.java
new file mode 100644
index 000000000000..04850d76bfc7
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OColumn.java
@@ -0,0 +1,279 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.XNamed;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.sdbc.ColumnValue;
+import com.sun.star.sdbcx.XDataDescriptorFactory;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertySetter;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxColumnDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class OColumn extends ODescriptor implements XNamed, XDataDescriptorFactory {
+ private String typeName;
+ private String description;
+ private String defaultValue;
+ private int isNullable;
+ private int precision;
+ private int scale;
+ private int type;
+ private boolean isAutoIncrement;
+ private boolean isRowVersion;
+ private boolean isCurrency;
+
+ protected OColumn(final Object lock, final boolean isCaseSensitive) {
+ super(lock, "", isCaseSensitive);
+ this.isNullable = ColumnValue.NULLABLE;
+ this.precision = 0;
+ this.scale = 0;
+ this.type = 0;
+ this.isAutoIncrement = false;
+ this.isRowVersion = false;
+ this.isCurrency = false;
+ registerProperties();
+ }
+
+ public static OColumn create(final boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new OColumn(lock, isCaseSensitive);
+ }
+
+ protected OColumn(
+ final Object lock,
+ final String name,
+ final String typeName,
+ final String defaultValue,
+ final String description,
+ final int isNullable,
+ final int precision,
+ final int scale,
+ final int type,
+ final boolean isAutoIncrement,
+ final boolean isRowVersion,
+ final boolean isCurrency,
+ final boolean isCaseSensitive) {
+ super(lock, name, isCaseSensitive);
+ this.typeName = typeName;
+ this.description = description;
+ this.defaultValue = defaultValue;
+ this.isNullable = isNullable;
+ this.precision = precision;
+ this.scale = scale;
+ this.type = type;
+ this.isAutoIncrement = isAutoIncrement;
+ this.isRowVersion = isRowVersion;
+ this.isCurrency = isCurrency;
+ registerProperties();
+ }
+
+ public static OColumn create(
+ final String name,
+ final String typeName,
+ final String defaultValue,
+ final String description,
+ final int isNullable,
+ final int precision,
+ final int scale,
+ final int type,
+ final boolean isAutoIncrement,
+ final boolean isRowVersion,
+ final boolean isCurrency,
+ final boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new OColumn(lock, name, typeName, defaultValue, description,
+ isNullable, precision, scale, type, isAutoIncrement, isRowVersion,
+ isCurrency, isCaseSensitive);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.TYPENAME.name, PropertyIds.TYPENAME.id, Type.STRING, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return typeName;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ typeName = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.DESCRIPTION.name, PropertyIds.DESCRIPTION.id, Type.STRING, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return description;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ description = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.DEFAULTVALUE.name, PropertyIds.DEFAULTVALUE.id, Type.STRING, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return defaultValue;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ defaultValue = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.PRECISION.name, PropertyIds.PRECISION.id, Type.LONG, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return precision;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ precision = (Integer) value;
+ }
+ });
+ registerProperty(PropertyIds.TYPE.name, PropertyIds.TYPE.id, Type.LONG, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return type;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ type = (Integer) value;
+ }
+ });
+ registerProperty(PropertyIds.SCALE.name, PropertyIds.SCALE.id, Type.LONG, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return scale;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ scale = (Integer) value;
+ }
+ });
+ registerProperty(PropertyIds.ISNULLABLE.name, PropertyIds.ISNULLABLE.id, Type.LONG, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isNullable;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isNullable = (Integer) value;
+ }
+ });
+ registerProperty(PropertyIds.ISAUTOINCREMENT.name, PropertyIds.ISAUTOINCREMENT.id, Type.BOOLEAN, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isAutoIncrement;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isAutoIncrement = (Boolean) value;
+ }
+ });
+ registerProperty(PropertyIds.ISROWVERSION.name, PropertyIds.ISROWVERSION.id, Type.BOOLEAN, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isRowVersion;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isRowVersion = (Boolean) value;
+ }
+ });
+ registerProperty(PropertyIds.ISCURRENCY.name, PropertyIds.ISCURRENCY.id, Type.BOOLEAN, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isCurrency;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isCurrency = (Boolean) value;
+ }
+ });
+ }
+
+ // XComponent
+
+ @Override
+ protected void postDisposing() {
+ super.postDisposing();
+ }
+
+ private void checkDisposed() {
+ if (bDisposed) {
+ throw new DisposedException();
+ }
+ }
+
+ // XDataDescriptorFactory
+
+ @Override
+ public XPropertySet createDataDescriptor() {
+ SdbcxColumnDescriptor descriptor = SdbcxColumnDescriptor.create(isCaseSensitive());
+ synchronized (lock) {
+ CompHelper.copyProperties(this, descriptor);
+ }
+ return descriptor;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OColumnContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OColumnContainer.java
new file mode 100644
index 000000000000..a50aa31f1f3a
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OColumnContainer.java
@@ -0,0 +1,123 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.sdbc.ColumnValue;
+import com.sun.star.sdbc.DataType;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XDatabaseMetaData;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.SqlTableHelper.ColumnDescription;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxColumnDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+import com.sun.star.uno.UnoRuntime;
+
+public class OColumnContainer extends OContainer {
+ private OTable table;
+ private XDatabaseMetaData metadata;
+ private Map<String,ColumnDescription> columnDescriptions = new HashMap<>();
+ private Map<String,ExtraColumnInfo> extraColumnInfo = new HashMap<>();
+
+ /// The XDatabaseMetaData.getColumns() data stored in columnDescriptions doesn't provide everything we need, so this class stores the rest.
+ public static class ExtraColumnInfo {
+ public boolean isAutoIncrement;
+ public boolean isCurrency;
+ public int dataType;
+ }
+
+ public OColumnContainer(Object lock, boolean isCaseSensitive, List<ColumnDescription> columnDescriptions, OTable table, XDatabaseMetaData metadata) {
+ super(lock, isCaseSensitive, toColumnNames(columnDescriptions));
+ this.table = table;
+ this.metadata = metadata;
+ for (ColumnDescription columnDescription : columnDescriptions) {
+ this.columnDescriptions.put(columnDescription.columnName, columnDescription);
+ }
+ }
+
+ private static List<String> toColumnNames(List<ColumnDescription> columns) {
+ List<String> columnNames = new ArrayList<>(columns.size());
+ for (ColumnDescription columnDescription : columns) {
+ columnNames.add(columnDescription.columnName);
+ }
+ return columnNames;
+ }
+
+ @Override
+ public XPropertySet createObject(String name) throws SQLException {
+ boolean queryInfo = true;
+ boolean isAutoIncrement = false;
+ boolean isCurrency = false;
+ int dataType = DataType.OTHER;
+ ExtraColumnInfo columnInfo = extraColumnInfo.get(name);
+ if (columnInfo == null) {
+ String composedName = DbTools.composeTableNameForSelect(metadata.getConnection(), table);
+ extraColumnInfo = DbTools.collectColumnInformation(metadata.getConnection(), composedName, "*");
+ columnInfo = extraColumnInfo.get(name);
+ }
+ if (columnInfo != null) {
+ queryInfo = false;
+ isAutoIncrement = columnInfo.isAutoIncrement;
+ isCurrency = columnInfo.isCurrency;
+ dataType = columnInfo.dataType;
+ }
+ ColumnDescription columnDescription = columnDescriptions.get(name);
+ if (columnDescription != null) {
+ XNameAccess primaryKeyColumns = DbTools.getPrimaryKeyColumns(UnoRuntime.queryInterface(XPropertySet.class, table));
+ int nullable = columnDescription.nullable;
+ if (nullable != ColumnValue.NO_NULLS && primaryKeyColumns != null && primaryKeyColumns.hasByName(name)) {
+ nullable = ColumnValue.NO_NULLS;
+ }
+ return OColumn.create(name, columnDescription.typeName, columnDescription.defaultValue, columnDescription.remarks,
+ nullable, columnDescription.columnSize, columnDescription.decimalDigits, columnDescription.type,
+ isAutoIncrement, false, isCurrency, isCaseSensitive());
+ } else {
+ // FIXME: do something like the C++ implementation does?
+ throw new SQLException();
+ }
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxColumnDescriptor.create(isCaseSensitive());
+ }
+
+ @Override
+ public void impl_refresh() {
+ extraColumnInfo.clear();
+ table.refreshColumns();
+ }
+
+ @Override
+ public XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void dropObject(int index, String name) throws SQLException {
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OContainer.java
new file mode 100644
index 000000000000..9f0ed55e2e04
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OContainer.java
@@ -0,0 +1,461 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.ContainerEvent;
+import com.sun.star.container.ElementExistException;
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.container.XContainer;
+import com.sun.star.container.XContainerListener;
+import com.sun.star.container.XEnumeration;
+import com.sun.star.container.XEnumerationAccess;
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.IndexOutOfBoundsException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lib.uno.helper.InterfaceContainer;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XColumnLocate;
+import com.sun.star.sdbcx.XAppend;
+import com.sun.star.sdbcx.XDataDescriptorFactory;
+import com.sun.star.sdbcx.XDrop;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.OEnumerationByIndex;
+import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.Type;
+import com.sun.star.util.XRefreshListener;
+import com.sun.star.util.XRefreshable;
+
+public abstract class OContainer extends WeakBase implements
+ XNameAccess, XIndexAccess, XEnumerationAccess,
+ XContainer, XColumnLocate, XRefreshable, XDataDescriptorFactory,
+ XAppend, XDrop, XServiceInfo {
+
+ private static String[] services = new String[] {
+ "com.sun.star.sdbcx.Container"
+ };
+
+ protected final Object lock;
+ private final boolean isCaseSensitive;
+ private TreeMap<String,HashMap<Long,XPropertySet>> entriesByNameAndId;
+ private ArrayList<PropertyInfo> entriesByIndex;
+ private long nextId;
+ private InterfaceContainer containerListeners = new InterfaceContainer();
+ private InterfaceContainer refreshListeners = new InterfaceContainer();
+
+ /// Names aren't necessarily unique, we have to de-duplicate by id.
+ private static class PropertyInfo {
+ String name;
+ long id;
+
+ PropertyInfo(String name, long id) {
+ this.name = name;
+ this.id = id;
+ }
+ }
+
+ private Comparator<String> caseSensitiveComparator = new Comparator<String>() {
+ @Override
+ public int compare(String x, String y) {
+ if (isCaseSensitive) {
+ return x.compareTo(y);
+ } else {
+ return x.compareToIgnoreCase(y);
+ }
+ }
+ };
+
+ public OContainer(Object lock, boolean isCaseSensitive, List<String> names) {
+ this.lock = lock;
+ this.isCaseSensitive = isCaseSensitive;
+ this.entriesByNameAndId = new TreeMap<String,HashMap<Long,XPropertySet>>(caseSensitiveComparator);
+ this.entriesByIndex = new ArrayList<>(names.size());
+ for (String name : names) {
+ HashMap<Long,XPropertySet> entriesById = entriesByNameAndId.get(name);
+ if (entriesById == null) {
+ entriesById = new HashMap<>();
+ entriesByNameAndId.put(name, entriesById);
+ }
+ entriesById.put(nextId, null);
+
+ entriesByIndex.add(new PropertyInfo(name, nextId));
+ ++nextId;
+ }
+ }
+
+ // Would be from XComponent ;)
+
+ public void dispose() {
+ EventObject event = new EventObject(this);
+ containerListeners.disposeAndClear(event);
+ refreshListeners.disposeAndClear(event);
+
+ synchronized (lock) {
+ for (Map<Long,XPropertySet> entriesById : entriesByNameAndId.values()) {
+ for (XPropertySet propertySet : entriesById.values()) {
+ CompHelper.disposeComponent(propertySet);
+ }
+ }
+ entriesByNameAndId.clear();
+ entriesByIndex.clear();
+ }
+ }
+
+ // XServiceInfo
+
+ public String getImplementationName() {
+ return "com.sun.star.sdbcx.VContainer";
+ }
+
+ @Override
+ public String[] getSupportedServiceNames() {
+ return services.clone();
+ }
+
+ @Override
+ public boolean supportsService(String serviceName) {
+ for (String service : services) {
+ if (service.equals(serviceName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // XIndexAccess
+
+ @Override
+ public Object getByIndex(int index) throws IndexOutOfBoundsException, WrappedTargetException {
+ synchronized (lock) {
+ if (index < 0 || index >= entriesByIndex.size()) {
+ throw new IndexOutOfBoundsException(Integer.toString(index), this);
+ }
+ return getObject(index);
+ }
+ }
+
+ @Override
+ public int getCount() {
+ synchronized (lock) {
+ return entriesByIndex.size();
+ }
+ }
+
+ // XNameAccess
+
+ @Override
+ public boolean hasByName(String name) {
+ synchronized (lock) {
+ return entriesByNameAndId.containsKey(name);
+ }
+ }
+
+ @Override
+ public Object getByName(String name) throws NoSuchElementException, WrappedTargetException {
+ synchronized (lock) {
+ if (!entriesByNameAndId.containsKey(name)) {
+ String error = SharedResources.getInstance().getResourceStringWithSubstitution(
+ Resources.STR_NO_ELEMENT_NAME, "$name$", name);
+ throw new NoSuchElementException(error, this);
+ }
+ return getObject(indexOf(name));
+ }
+ }
+
+ @Override
+ public String[] getElementNames() {
+ synchronized (lock) {
+ String[] names = new String[entriesByIndex.size()];
+ int next = 0;
+ for (PropertyInfo propertyInfo : entriesByIndex) {
+ names[next++] = propertyInfo.name;
+ }
+ return names;
+ }
+ }
+
+ // XRefreshable
+
+ @Override
+ public void refresh() {
+ Iterator iterator;
+ synchronized (lock) {
+ for (Map<Long,XPropertySet> entriesById : entriesByNameAndId.values()) {
+ for (XPropertySet propertySet : entriesById.values()) {
+ CompHelper.disposeComponent(propertySet);
+ }
+ }
+ entriesByNameAndId.clear();
+ entriesByIndex.clear();
+
+ impl_refresh();
+
+ iterator = refreshListeners.iterator();
+ }
+ EventObject event = new EventObject(this);
+ while (iterator.hasNext()) {
+ XRefreshListener listener = (XRefreshListener) iterator.next();
+ listener.refreshed(event);
+ }
+ }
+
+ // XDataDescriptorFactory
+
+ @Override
+ public XPropertySet createDataDescriptor() {
+ synchronized (lock) {
+ return createDescriptor();
+ }
+ }
+
+ protected String getNameForObject(XPropertySet object) {
+ try {
+ Object ret = object.getPropertyValue("Name");
+ return AnyConverter.toString(ret);
+ } catch (WrappedTargetException wrappedTargetException) {
+ } catch (UnknownPropertyException unknownPropertyException) {
+ } catch (IllegalArgumentException illegalArgumentException) {
+ }
+ return null;
+ }
+
+ // XAppend
+
+ @Override
+ public void appendByDescriptor(XPropertySet descriptor) throws SQLException, ElementExistException {
+ Iterator iterator;
+ ContainerEvent event;
+ synchronized (lock) {
+ String name = getNameForObject(descriptor);
+
+ if (entriesByNameAndId.containsKey(name)) {
+ throw new ElementExistException(name, this);
+ }
+
+ XPropertySet newlyCreated = appendObject(name, descriptor);
+ if (newlyCreated == null) {
+ throw new RuntimeException();
+ }
+
+ name = getNameForObject(newlyCreated);
+ HashMap<Long,XPropertySet> entriesById = entriesByNameAndId.get(name);
+ if (entriesById == null) { // this may happen when the derived class included it itself
+ entriesById = new HashMap<>();
+ entriesById.put(nextId, newlyCreated);
+ entriesByNameAndId.put(name, entriesById);
+ entriesByIndex.add(new PropertyInfo(name, nextId));
+ nextId++;
+ }
+
+ // notify our container listeners
+ event = new ContainerEvent(this, name, newlyCreated, null);
+ iterator = containerListeners.iterator();
+ }
+ while (iterator.hasNext()) {
+ XContainerListener listener = (XContainerListener) iterator.next();
+ listener.elementInserted(event);
+ }
+
+ }
+
+ // XDrop
+
+ @Override
+ public void dropByName(String name) throws SQLException, NoSuchElementException {
+ synchronized (lock) {
+ if (!entriesByNameAndId.containsKey(name)) {
+ throw new NoSuchElementException(name, this);
+ }
+ dropImpl(indexOf(name));
+ }
+ }
+
+ @Override
+ public void dropByIndex(int index) throws SQLException, IndexOutOfBoundsException {
+ synchronized (lock) {
+ if (index < 0 || index >= entriesByIndex.size()) {
+ throw new IndexOutOfBoundsException(Integer.toString(index), this);
+ }
+ dropImpl(index);
+ }
+ }
+
+
+ private void dropImpl(int index) throws SQLException {
+ dropImpl(index, true);
+ }
+
+ private void dropImpl(int index, boolean reallyDrop) throws SQLException {
+ PropertyInfo propertyInfo = entriesByIndex.get(index);
+ if (reallyDrop) {
+ dropObject(index, propertyInfo.name);
+ }
+ HashMap<Long,XPropertySet> entriesById = entriesByNameAndId.get(propertyInfo.name);
+ XPropertySet propertySet = entriesById.remove(propertyInfo.id);
+ if (entriesById.isEmpty()) {
+ entriesByNameAndId.remove(propertyInfo.name);
+ }
+ CompHelper.disposeComponent(propertySet);
+ entriesByIndex.remove(index);
+
+ ContainerEvent event = new ContainerEvent(this, propertyInfo.name, null, null);
+ for (Iterator iterator = containerListeners.iterator(); iterator.hasNext(); ) {
+ XContainerListener listener = (XContainerListener) iterator.next();
+ listener.elementRemoved(event);
+ }
+ }
+
+ // XColumnLocate
+
+ @Override
+ public int findColumn(String name) throws SQLException {
+ if (!entriesByNameAndId.containsKey(name)) {
+ String error = SharedResources.getInstance().getResourceStringWithSubstitution(
+ Resources.STR_UNKNOWN_COLUMN_NAME, "$columnname$", name);
+ throw new SQLException(error, this, StandardSQLState.SQL_COLUMN_NOT_FOUND.text(), 0, null);
+ }
+ return indexOf(name) + 1; // because columns start at one
+ }
+
+
+ // XEnumerationAccess
+
+ @Override
+ public XEnumeration createEnumeration() {
+ return new OEnumerationByIndex(this);
+ }
+
+ @Override
+ public void addContainerListener(XContainerListener listener) {
+ containerListeners.add(listener);
+ }
+
+ @Override
+ public void removeContainerListener(XContainerListener listener) {
+ containerListeners.remove(listener);
+ }
+
+ @Override
+ public Type getElementType() {
+ return new Type(XPropertySet.class);
+ }
+
+ @Override
+ public boolean hasElements() {
+ synchronized (lock) {
+ return !entriesByNameAndId.isEmpty();
+ }
+ }
+
+ @Override
+ public void addRefreshListener(XRefreshListener listener) {
+ synchronized (lock) {
+ refreshListeners.add(listener);
+ }
+ }
+
+ @Override
+ public void removeRefreshListener(XRefreshListener listener) {
+ synchronized (lock) {
+ refreshListeners.remove(listener);
+ }
+ }
+
+ protected int indexOf(String name) {
+ for (int i = 0; i < entriesByIndex.size(); i++) {
+ if (entriesByIndex.get(i).name.equals(name)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ protected Object getObject(int index) throws WrappedTargetException {
+ PropertyInfo propertyInfo = entriesByIndex.get(index);
+ HashMap<Long,XPropertySet> entriesById = entriesByNameAndId.get(propertyInfo.name);
+ XPropertySet propertySet = entriesById.get(propertyInfo.id);
+ if (propertySet == null) {
+ try {
+ propertySet = createObject(propertyInfo.name);
+ } catch (SQLException e) {
+ try {
+ dropImpl(index, false);
+ } catch (Exception ignored) {
+ }
+ throw new WrappedTargetException(e.getMessage(), this, e);
+ }
+ entriesById.put(propertyInfo.id, propertySet);
+ }
+ return propertySet;
+ }
+
+ protected XPropertySet cloneDescriptor(XPropertySet descriptor) {
+ XPropertySet newDescriptor = createDescriptor();
+ CompHelper.copyProperties(descriptor, newDescriptor);
+ return newDescriptor;
+ }
+
+ protected boolean isCaseSensitive() {
+ return isCaseSensitive;
+ }
+
+ // will be called when a object was requested by one of the accessing methods like getByIndex
+ public abstract XPropertySet createObject(final String name) throws SQLException;
+
+ public abstract void dropObject(int index, String name) throws SQLException;
+
+ // the implementing class should refresh their elements
+ public abstract void impl_refresh();
+
+ // will be called when a new object should be generated by a call of createDataDescriptor
+ // the returned object is empty will be filled outside and added to the collection
+ public abstract XPropertySet createDescriptor();
+
+ /** appends an object described by a descriptor, under a given name
+ @param _rForName
+ is the name under which the object should be appended. Guaranteed to not be empty.
+ This is passed for convenience only, since it's the result of a call of
+ getNameForObject for the given descriptor
+ @param descriptor
+ describes the object to append
+ @return
+ the new object which is to be inserted into the collection. This might be the result
+ of a call of <code>createObject( _rForName )</code>, or a clone of the descriptor.
+ */
+ public abstract XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException;
+
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/ODescriptor.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/ODescriptor.java
new file mode 100644
index 000000000000..d885eae09611
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/ODescriptor.java
@@ -0,0 +1,76 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySet;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertySetter;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class ODescriptor extends PropertySet {
+ private String name;
+ private final boolean isCaseSensitive;
+ protected final Object lock;
+
+ public ODescriptor(Object lock, String name, boolean isCaseSensitive, boolean isReadOnly) {
+ super(lock);
+ this.lock = lock;
+ this.name = name;
+ this.isCaseSensitive = isCaseSensitive;
+ registerProperties(isReadOnly);
+ }
+
+ public ODescriptor(Object lock, String name, boolean isCaseSensitive) {
+ this(lock, name, isCaseSensitive, true);
+ }
+
+ private void registerProperties(boolean isReadOnly) {
+ registerProperty(PropertyIds.NAME.name, PropertyIds.NAME.id, Type.STRING, isReadOnly ? PropertyAttribute.READONLY : 0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return name;
+
+ }
+ },
+ isReadOnly ? null : new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ name = (String) value;
+ }
+ });
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isCaseSensitive() {
+ return isCaseSensitive;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndex.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndex.java
new file mode 100644
index 000000000000..e2d2c2df2a02
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndex.java
@@ -0,0 +1,121 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.List;
+
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.XDataDescriptorFactory;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxIndexDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class OIndex extends ODescriptor implements XColumnsSupplier, XDataDescriptorFactory {
+ protected String catalogName;
+ protected boolean isUnique;
+ protected boolean isPrimaryKeyIndex;
+ protected boolean isClustered;
+ private OTable table;
+ private OContainer columns;
+
+ protected OIndex(Object lock, String name, boolean isCaseSensitive, String catalogName,
+ boolean isUnique, boolean isPrimaryKeyIndex, boolean isClustered, List<String> columnNames, OTable table) {
+ super(lock, name, isCaseSensitive);
+ this.catalogName = catalogName;
+ this.isUnique = isUnique;
+ this.isPrimaryKeyIndex = isPrimaryKeyIndex;
+ this.isClustered = isClustered;
+ this.table = table;
+ columns = new OIndexColumnContainer(lock, this, columnNames);
+ registerProperties();
+ }
+
+ public static OIndex create(String name, boolean isCaseSensitive, String catalogName,
+ boolean isUnique, boolean isPrimaryKeyIndex, boolean isClustered, List<String> columnNames, OTable table) {
+ final Object lock = new Object();
+ return new OIndex(lock, name, isCaseSensitive, catalogName, isUnique, isPrimaryKeyIndex, isClustered, columnNames, table);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.CATALOG.name, PropertyIds.CATALOG.id, Type.STRING, (short)PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return catalogName;
+ }
+ }, null);
+ registerProperty(PropertyIds.ISPRIMARYKEYINDEX.name, PropertyIds.ISPRIMARYKEYINDEX.id, Type.BOOLEAN, (short)PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isPrimaryKeyIndex;
+ }
+ }, null);
+ registerProperty(PropertyIds.ISCLUSTERED.name, PropertyIds.ISCLUSTERED.id, Type.BOOLEAN, (short)PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isClustered;
+ }
+ }, null);
+ registerProperty(PropertyIds.ISUNIQUE.name, PropertyIds.ISUNIQUE.id, Type.BOOLEAN, (short)PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isUnique;
+ }
+ }, null);
+ }
+
+ @Override
+ public XPropertySet createDataDescriptor() {
+ SdbcxIndexDescriptor descriptor = SdbcxIndexDescriptor.create(isCaseSensitive());
+ CompHelper.copyProperties(this, descriptor);
+ try {
+ DbTools.cloneDescriptorColumns(this, descriptor);
+ } catch (SQLException sqlException) {
+ }
+ return descriptor;
+ }
+
+ @Override
+ public XNameAccess getColumns() {
+ return columns;
+ }
+
+ public OTable getTable() {
+ return table;
+ }
+
+ @Override
+ public String toString() {
+ return "OIndex [catalogName=" + catalogName + ", isUnique=" + isUnique + ", isPrimaryKeyIndex=" + isPrimaryKeyIndex + ", isClustered=" + isClustered
+ + ", name=" + getName() + "]";
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexColumn.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexColumn.java
new file mode 100644
index 000000000000..7c29d2ec6d1e
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexColumn.java
@@ -0,0 +1,96 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxIndexColumnDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class OIndexColumn extends OColumn {
+ protected boolean isAscending;
+
+ protected OIndexColumn(
+ final Object lock,
+ final boolean isAscending,
+ final String name,
+ final String typeName,
+ final String defaultValue,
+ final String description,
+ final int isNullable,
+ final int precision,
+ final int scale,
+ final int type,
+ final boolean isAutoIncrement,
+ final boolean isRowVersion,
+ final boolean isCurrency,
+ final boolean isCaseSensitive) {
+ super(lock, name, typeName, defaultValue, description, isNullable,
+ precision, scale, type, isAutoIncrement, isRowVersion, isCurrency, isCaseSensitive);
+ this.isAscending = isAscending;
+ registerProperties();
+ }
+
+ public static OIndexColumn create(
+ final boolean isAscending,
+ final String name,
+ final String typeName,
+ final String defaultValue,
+ final int isNullable,
+ final int precision,
+ final int scale,
+ final int type,
+ final boolean isAutoIncrement,
+ final boolean isRowVersion,
+ final boolean isCurrency,
+ final boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new OIndexColumn(lock, isAscending, name, typeName,
+ defaultValue, "", isNullable, precision, scale,
+ type, isAutoIncrement, isRowVersion, isCurrency, isCaseSensitive);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.ISASCENDING.name, PropertyIds.ISASCENDING.id, Type.BOOLEAN, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isAscending;
+
+ }
+ }, null);
+ }
+
+ // XDataDescriptorFactory
+
+ @Override
+ public XPropertySet createDataDescriptor() {
+ SdbcxIndexColumnDescriptor descriptor = SdbcxIndexColumnDescriptor.create(isCaseSensitive());
+ synchronized (lock) {
+ CompHelper.copyProperties(this, descriptor);
+ }
+ return descriptor;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexColumnContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexColumnContainer.java
new file mode 100644
index 000000000000..5e6db41bed7b
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexColumnContainer.java
@@ -0,0 +1,121 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.List;
+
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxIndexColumnDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+
+public class OIndexColumnContainer extends OContainer {
+ private OIndex index;
+
+ public OIndexColumnContainer(Object lock, OIndex index, List<String> columnNames) {
+ super(lock, true, columnNames);
+ this.index = index;
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxIndexColumnDescriptor.create(isCaseSensitive());
+ }
+
+ @Override
+ public XPropertySet createObject(String name) throws SQLException {
+ try {
+ Object catalog = index.getTable().getPropertyValue(PropertyIds.CATALOGNAME.name);
+ String schema = AnyConverter.toString(index.getTable().getPropertyValue(PropertyIds.SCHEMANAME.name));
+ String table = AnyConverter.toString(index.getTable().getPropertyValue(PropertyIds.NAME.name));
+
+ boolean isAscending = true;
+ XResultSet results = null;
+ try {
+ results = index.getTable().getConnection().getMetaData().getIndexInfo(catalog, schema, table, false, false);
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ while (results.next()) {
+ if (row.getString(9).equals(name)) {
+ isAscending = !row.getString(10).equals("D");
+ }
+ }
+ }
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+
+ XPropertySet ret = null;
+ results = null;
+ try {
+ results = index.getTable().getConnection().getMetaData().getColumns(catalog, schema, table, name);
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ while (results.next()) {
+ if (row.getString(4).equals(name)) {
+ int dataType = row.getInt(5);
+ String typeName = row.getString(6);
+ int size = row.getInt(7);
+ int dec = row.getInt(9);
+ int nul = row.getInt(11);
+ String columnDef = row.getString(13);
+
+ ret = OIndexColumn.create(isAscending, name, typeName, columnDef,
+ nul, size, dec, dataType, false, false, false, isCaseSensitive());
+ break;
+ }
+ }
+ }
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+
+ return ret;
+ } catch (WrappedTargetException | UnknownPropertyException | IllegalArgumentException exception) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, exception);
+ }
+ }
+
+ @Override
+ public void impl_refresh() {
+ // FIXME
+ }
+
+ @Override
+ public XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException {
+ throw new SQLException("Unsupported");
+ }
+
+ @Override
+ public void dropObject(int index, String name) throws SQLException {
+ throw new SQLException("Unsupported");
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexContainer.java
new file mode 100644
index 000000000000..c5109335a616
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OIndexContainer.java
@@ -0,0 +1,208 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.IndexOutOfBoundsException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.sdbc.IndexType;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbc.XDatabaseMetaData;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbc.XStatement;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxIndexDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.ComposeRule;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+
+public class OIndexContainer extends OContainer {
+ protected OTable table;
+
+ public OIndexContainer(Object lock, List<String> names, boolean isCaseSensitive, OTable table) {
+ super(lock, isCaseSensitive, names);
+ this.table = table;
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxIndexDescriptor.create(isCaseSensitive());
+ }
+
+ @Override
+ public XPropertySet createObject(String name) throws SQLException {
+ try {
+ XConnection connection = table.getConnection();
+ if (connection == null) {
+ return null;
+ }
+
+ XPropertySet ret = null;
+ String qualifier = "";
+ String subname;
+ int len = name.indexOf('.');
+ if (len >= 0) {
+ qualifier = name.substring(0, len);
+ subname = name.substring(len + 1);
+ } else {
+ subname = name;
+ }
+
+ Object catalog = table.getPropertyValue(PropertyIds.CATALOGNAME.name);
+ String schemaName = AnyConverter.toString(table.getPropertyValue(PropertyIds.SCHEMANAME.name));
+ String tableName = AnyConverter.toString(table.getPropertyValue(PropertyIds.NAME.name));
+ XResultSet results = null;
+ try {
+ results = connection.getMetaData().getIndexInfo(catalog, schemaName, tableName, false, false);
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ boolean found = false;
+ boolean isUnique = false;
+ int clustered = -1;
+ boolean isPrimaryKeyIndex = false;
+ ArrayList<String> columnNames = new ArrayList<>();
+ while (results.next()) {
+ isUnique = !row.getBoolean(4);
+ if ((qualifier.isEmpty() || row.getString(5).equals(qualifier)) && row.getString(6).equals(subname)) {
+ found = true;
+ clustered = row.getShort(7);
+ isPrimaryKeyIndex = isPrimaryKeyIndex(connection.getMetaData(), catalog, schemaName, tableName, subname);
+ String columnName = row.getString(9);
+ if (!row.wasNull()) {
+ columnNames.add(columnName);
+ }
+ }
+ }
+ if (found) {
+ ret = OIndex.create(subname, isCaseSensitive(), qualifier, isUnique, isPrimaryKeyIndex, clustered == IndexType.CLUSTERED,
+ columnNames, table);
+ }
+ }
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+ return ret;
+ } catch (WrappedTargetException | UnknownPropertyException | IllegalArgumentException exception) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, exception);
+ }
+ }
+
+ private static boolean isPrimaryKeyIndex(XDatabaseMetaData metadata, Object catalog, String schema, String table, String name) throws SQLException {
+ XResultSet results = null;
+ try {
+ results = metadata.getPrimaryKeys(catalog, schema, table);
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ if (results.next()) { // there can be only one primary key
+ return row.getString(6).equals(name);
+ }
+ }
+ return false;
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+ }
+
+ @Override
+ public XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException {
+ try {
+ XConnection connection = table.getConnection();
+ if (connection == null) {
+ return null;
+ }
+ String quote = connection.getMetaData().getIdentifierQuoteString();
+ boolean isUnique = AnyConverter.toBoolean(descriptor.getPropertyValue(PropertyIds.ISUNIQUE.name));
+ String composedName = DbTools.composeTableName(connection.getMetaData(), table, ComposeRule.InIndexDefinitions, false, false, true);
+ StringBuilder columnsText = new StringBuilder();
+ String separator = "";
+ XColumnsSupplier columnsSupplier = UnoRuntime.queryInterface(XColumnsSupplier.class, descriptor);
+ XIndexAccess columns = UnoRuntime.queryInterface(XIndexAccess.class, columnsSupplier.getColumns());
+ for (int i = 0; i < columns.getCount(); i++) {
+ columnsText.append(separator);
+ separator = ", ";
+ XPropertySet column = AnyConverter.toObject(XPropertySet.class, columns.getByIndex(i));
+ columnsText.append(DbTools.quoteName(quote, AnyConverter.toString(column.getPropertyValue(PropertyIds.NAME.name))));
+ // FIXME: ::dbtools::getBooleanDataSourceSetting( m_pTable->getConnection(), "AddIndexAppendix" );
+ boolean isAscending = AnyConverter.toBoolean(column.getPropertyValue(PropertyIds.ISASCENDING.name));
+ columnsText.append(isAscending ? " ASC" : " DESC");
+ }
+ String sql = String.format("CREATE %s INDEX %s ON %s (%s)",
+ isUnique ? "UNIQUE" : "",
+ _rForName.isEmpty() ? "" : DbTools.quoteName(quote, _rForName),
+ composedName,
+ columnsText.toString());
+ XStatement statement = null;
+ try {
+ statement = connection.createStatement();
+ statement.execute(sql);
+ } finally {
+ CompHelper.disposeComponent(statement);
+ }
+ return createObject(_rForName);
+ } catch (WrappedTargetException | UnknownPropertyException | IllegalArgumentException | IndexOutOfBoundsException exception) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, exception);
+ }
+ }
+
+ @Override
+ public void dropObject(int index, String elementName) throws SQLException {
+ XConnection connection = table.getConnection();
+ if (connection == null) {
+ return;
+ }
+ String name;
+ String schema = "";
+ int len = elementName.indexOf('.');
+ if (len >= 0) {
+ schema = elementName.substring(0, len);
+ }
+ name = elementName.substring(len + 1);
+
+ String composedName = DbTools.composeTableName(connection.getMetaData(), table, ComposeRule.InTableDefinitions, false, false, true);
+ String indexName = DbTools.composeTableName(connection.getMetaData(), "", schema, name, true, ComposeRule.InIndexDefinitions);
+ String sql = String.format("DROP INDEX %s ON %s", indexName, composedName);
+ XStatement statement = null;
+ try {
+ statement = connection.createStatement();
+ statement.execute(sql);
+ } finally {
+ CompHelper.disposeComponent(statement);
+ }
+ }
+
+ @Override
+ public void impl_refresh() {
+ // FIXME
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKey.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKey.java
new file mode 100644
index 000000000000..6ebae316be41
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKey.java
@@ -0,0 +1,150 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.List;
+
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.XDataDescriptorFactory;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxKeyDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class OKey extends ODescriptor
+ implements XDataDescriptorFactory, XColumnsSupplier {
+
+ protected OTable table;
+ protected String referencedTable;
+ protected int type;
+ protected int updateRule;
+ protected int deleteRule;
+
+ private OContainer columns;
+
+ protected OKey(Object lock, boolean isCaseSensitive) {
+ super(lock, "", isCaseSensitive);
+ registerProperties();
+ }
+
+ protected OKey(Object lock, String name, boolean isCaseSensitive, String referencedTable, int type,
+ int updateRule, int deleteRule, List<String> columnNames, OTable table) {
+ super(lock, name, isCaseSensitive);
+ this.referencedTable = referencedTable;
+ this.type = type;
+ this.updateRule = updateRule;
+ this.deleteRule = deleteRule;
+ this.table = table;
+ registerProperties();
+ columns = new OKeyColumnContainer(lock, this, columnNames);
+ }
+
+ public static OKey create(String name, boolean isCaseSensitive, String referencedTable, int type,
+ int updateRule, int deleteRule, List<String> columnNames, OTable table) {
+ final Object lock = new Object();
+ return new OKey(lock, name, isCaseSensitive, referencedTable, type, updateRule, deleteRule, columnNames, table);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.REFERENCEDTABLE.name, PropertyIds.REFERENCEDTABLE.id, Type.STRING, (short)PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return referencedTable;
+
+ }
+ }, null);
+ registerProperty(PropertyIds.TYPE.name, PropertyIds.TYPE.id, Type.LONG, (short)PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return type;
+
+ }
+ }, null);
+ registerProperty(PropertyIds.UPDATERULE.name, PropertyIds.UPDATERULE.id, Type.LONG, (short)PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return updateRule;
+
+ }
+ }, null);
+ registerProperty(PropertyIds.DELETERULE.name, PropertyIds.DELETERULE.id, Type.LONG, (short)PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return deleteRule;
+
+ }
+ }, null);
+ }
+
+ // XComponent
+
+ private void checkDisposed() {
+ if (bDisposed) {
+ throw new DisposedException();
+ }
+ }
+
+ // XColumnsSupplier
+
+ @Override
+ public XNameAccess getColumns() {
+ synchronized (lock) {
+ checkDisposed();
+ return columns;
+ }
+ }
+
+ // XDataDescriptionFactory
+
+ public XPropertySet createDataDescriptor() {
+ SdbcxKeyDescriptor descriptor = SdbcxKeyDescriptor.create(isCaseSensitive());
+ CompHelper.copyProperties(this, descriptor);
+ try {
+ DbTools.cloneDescriptorColumns(this, descriptor);
+ } catch (SQLException sqlException) {
+ }
+ return descriptor;
+ }
+
+ public OTable getTable() {
+ return table;
+ }
+
+ @Override
+ public String toString() {
+ return "OKey [referencedTable=" + referencedTable + ", type=" + type + ", updateRule=" + updateRule + ", deleteRule=" + deleteRule
+ + ", name=" + getName() + "]";
+ }
+
+
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyColumn.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyColumn.java
new file mode 100644
index 000000000000..d7f409f882d0
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyColumn.java
@@ -0,0 +1,101 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxKeyColumnDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class OKeyColumn extends OColumn {
+ protected String referencedColumn;
+
+ protected OKeyColumn(Object lock, boolean isCaseSensitive) {
+ super(lock, isCaseSensitive);
+ registerProperties();
+ }
+
+ protected OKeyColumn(
+ final Object lock,
+ final String referencedColumn,
+ final String name,
+ final String typeName,
+ final String defaultValue,
+ final String description,
+ final int isNullable,
+ final int precision,
+ final int scale,
+ final int type,
+ final boolean isAutoIncrement,
+ final boolean isRowVersion,
+ final boolean isCurrency,
+ final boolean isCaseSensitive) {
+ super(lock, name, typeName, defaultValue, description, isNullable,
+ precision, scale, type, isAutoIncrement, isRowVersion, isCurrency, isCaseSensitive);
+ this.referencedColumn = referencedColumn;
+ registerProperties();
+ }
+
+ public static OKeyColumn create(
+ final String referencedColumn,
+ final String name,
+ final String typeName,
+ final String defaultValue,
+ final int isNullable,
+ final int precision,
+ final int scale,
+ final int type,
+ final boolean isAutoIncrement,
+ final boolean isRowVersion,
+ final boolean isCurrency,
+ final boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new OKeyColumn(lock, referencedColumn, name, typeName,
+ defaultValue, "", isNullable, precision, scale,
+ type, isAutoIncrement, isRowVersion, isCurrency, isCaseSensitive);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.RELATEDCOLUMN.name, PropertyIds.RELATEDCOLUMN.id, Type.STRING, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return referencedColumn;
+
+ }
+ }, null);
+ }
+
+ // XDataDescriptorFactory
+
+ @Override
+ public XPropertySet createDataDescriptor() {
+ SdbcxKeyColumnDescriptor descriptor = SdbcxKeyColumnDescriptor.create(isCaseSensitive());
+ synchronized (lock) {
+ CompHelper.copyProperties(this, descriptor);
+ }
+ return descriptor;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyColumnContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyColumnContainer.java
new file mode 100644
index 000000000000..0fc5aa495589
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyColumnContainer.java
@@ -0,0 +1,115 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.List;
+
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxKeyColumnDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+
+public class OKeyColumnContainer extends OContainer {
+ private OKey key;
+
+ public OKeyColumnContainer(Object lock, OKey key, List<String> columnNames) {
+ super(lock, true, columnNames);
+ this.key = key;
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxKeyColumnDescriptor.create(isCaseSensitive());
+ }
+
+ @Override
+ public XPropertySet createObject(String name) throws SQLException {
+ try {
+ XPropertySet tableProperties = UnoRuntime.queryInterface(XPropertySet.class, key.getTable());
+ Object catalog = tableProperties.getPropertyValue(PropertyIds.CATALOGNAME.name);
+ String schema = AnyConverter.toString(tableProperties.getPropertyValue(PropertyIds.SCHEMANAME.name));
+ String table = AnyConverter.toString(tableProperties.getPropertyValue(PropertyIds.NAME.name));
+
+ XResultSet results = key.getTable().getConnection().getMetaData().getImportedKeys(catalog, schema, table);
+ String refColumnName = "";
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ while (results.next()) {
+ if (row.getString(8).equals(name) && key.getName().equals(row.getString(12))) {
+ refColumnName = row.getString(4);
+ break;
+ }
+ }
+ }
+
+ XPropertySet ret = null;
+ // now describe the column name and set its related column
+ results = key.getTable().getConnection().getMetaData().getColumns(catalog, schema, table, name);
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ if (results.next()) {
+ if (row.getString(4).equals(name)) {
+ int dataType = row.getInt(5);
+ String typeName = row.getString(6);
+ int size = row.getInt(7);
+ int dec = row.getInt(9);
+ int nul = row.getInt(11);
+ String columnDef = "";
+ try {
+ columnDef = row.getString(13);
+ } catch (SQLException sqlException) {
+ // sometimes we get an error when asking for this param
+ }
+ ret = OKeyColumn.create(refColumnName, name, typeName,
+ columnDef, nul, size, dec, dataType, false, false, false, isCaseSensitive());
+
+ }
+ }
+ }
+ return ret;
+ } catch (WrappedTargetException | UnknownPropertyException | IllegalArgumentException exception) {
+ throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, exception);
+ }
+ }
+
+ @Override
+ public void impl_refresh() {
+ }
+
+ @Override
+ public XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException {
+ throw new SQLException("Cannot change a key's columns, please delete and re-create the key instead");
+ }
+
+ @Override
+ public void dropObject(int index, String name) throws SQLException {
+ throw new SQLException("Cannot change a key's columns, please delete and re-create the key instead");
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyContainer.java
new file mode 100644
index 000000000000..d00f9018a115
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OKeyContainer.java
@@ -0,0 +1,277 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.container.XNamed;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.IndexOutOfBoundsException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.sdbc.KeyRule;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbc.XStatement;
+import com.sun.star.sdbcx.KeyType;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxKeyDescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.ComposeRule;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+
+public class OKeyContainer extends OContainer {
+ private OTable table;
+ private Map<String,OKey> keys;
+
+ protected OKeyContainer(Object lock, boolean isCaseSensitive, List<String> names, Map<String,OKey> keys, OTable table) {
+ super(lock, isCaseSensitive, names);
+ System.out.println("Keys.size()=" + keys.size());
+ for (Map.Entry<String,OKey> entry : keys.entrySet()) {
+ System.out.println(entry.getKey() + " => " + entry.getValue().referencedTable);
+ XIndexAccess cols = UnoRuntime.queryInterface(XIndexAccess.class, entry.getValue().getColumns());
+ try {
+ System.out.println("" + cols.getCount() + " columns:");
+ for (int i =0; i < cols.getCount(); i++) {
+ System.out.println(" " + AnyConverter.toObject(XNamed.class, cols.getByIndex(i)).getName());
+ }
+ } catch (WrappedTargetException wrappedTargetException) {
+ wrappedTargetException.printStackTrace();
+ } catch (IndexOutOfBoundsException indexOutOfBoundsException) {
+ indexOutOfBoundsException.printStackTrace();
+ } catch (IllegalArgumentException argumentException) {
+ argumentException.printStackTrace();
+ }
+ }
+ this.keys = keys;
+ this.table = table;
+ }
+
+ public static OKeyContainer create(boolean isCaseSensitive, Map<String,OKey> keys, OTable table) {
+ final Object lock = new Object();
+ String[] names = new String[keys.size()];
+ keys.keySet().toArray(names);
+ return new OKeyContainer(lock, isCaseSensitive, Arrays.asList(names), keys, table);
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxKeyDescriptor.create(isCaseSensitive());
+ }
+
+ @Override
+ public XPropertySet createObject(String name) throws SQLException {
+ OKey ret = null;
+
+ if (!name.isEmpty()) {
+ ret = keys.get(name);
+ }
+
+ if (ret == null) { // we have a primary key with a system name
+ // FIXME: so why was this exactly the same?
+ ret = keys.get(name);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public void impl_refresh() {
+ //throw new NotImplementedException("");
+ }
+
+ @Override
+ public XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException {
+ XConnection connection = table.getConnection();
+ if (connection == null) {
+ return null;
+ }
+ try {
+ int keyType = AnyConverter.toInt(descriptor.getPropertyValue(PropertyIds.TYPE.name));
+ int updateRule = 0;
+ int deleteRule = 0;
+ String referencedName = "";
+ if (keyType == KeyType.FOREIGN) {
+ referencedName = AnyConverter.toString(descriptor.getPropertyValue(PropertyIds.UPDATERULE.name));
+ updateRule = AnyConverter.toInt(descriptor.getPropertyValue(PropertyIds.UPDATERULE.name));
+ deleteRule = AnyConverter.toInt(descriptor.getPropertyValue(PropertyIds.DELETERULE.name));
+ }
+
+ String quote = connection.getMetaData().getIdentifierQuoteString();
+ String tableName = DbTools.composeTableName(connection.getMetaData(), table, ComposeRule.InTableDefinitions, false, false, true);
+
+ String keyTypeString;
+ if (keyType == KeyType.PRIMARY) {
+ keyTypeString = "PRIMARY KEY";
+ } else if (keyType == KeyType.FOREIGN) {
+ keyTypeString = "FOREIGN KEY";
+ } else {
+ throw new SQLException();
+ }
+
+ StringBuilder columnsText = new StringBuilder();
+ XColumnsSupplier columnsSupplier = UnoRuntime.queryInterface(XColumnsSupplier.class, descriptor);
+ XIndexAccess columns = UnoRuntime.queryInterface(XIndexAccess.class, columnsSupplier.getColumns());
+ String separator = "";
+ for (int i = 0; i < columns.getCount(); i++) {
+ columnsText.append(separator);
+ separator = ",";
+ XPropertySet columnProperties = AnyConverter.toObject(XPropertySet.class, columns.getByIndex(i));
+ columnsText.append(DbTools.quoteName(quote, AnyConverter.toString(columnProperties.getPropertyValue(PropertyIds.NAME.name))));
+ }
+
+ String sql = String.format("ALTER TABLE %s ADD %s (%s)", tableName, keyTypeString, columnsText.toString());
+
+ if (keyType == KeyType.FOREIGN) {
+ String quotedTableName = DbTools.quoteTableName(connection.getMetaData(), referencedName, ComposeRule.InTableDefinitions);
+ StringBuilder relatedColumns = new StringBuilder();
+ separator = "";
+ for (int i = 0; i < columns.getCount(); i++) {
+ relatedColumns.append(separator);
+ separator = ",";
+ XPropertySet columnProperties = AnyConverter.toObject(XPropertySet.class, columns.getByIndex(i));
+ relatedColumns.append(DbTools.quoteName(quote, AnyConverter.toString(columnProperties.getPropertyValue(PropertyIds.RELATEDCOLUMN.name))));
+ }
+ sql += String.format(" REFERENCES %s (%s)%s%s", quotedTableName, relatedColumns.toString(),
+ getKeyRuleString(true, updateRule), getKeyRuleString(false, deleteRule));
+ }
+ XStatement statement = null;
+ try {
+ statement = connection.createStatement();
+ statement.execute(sql);
+ } finally {
+ CompHelper.disposeComponent(statement);
+ }
+
+ // find the name which the database gave the new key
+ String newName = _rForName;
+ try {
+ String schema = AnyConverter.toString(this.table.getPropertyValue(PropertyIds.SCHEMANAME.name));
+ String table = AnyConverter.toString(this.table.getPropertyValue(PropertyIds.TABLENAME.name));
+ XResultSet results = null;
+ try {
+ final int column;
+ if (keyType == KeyType.FOREIGN) {
+ results = connection.getMetaData().getImportedKeys(this.table.getPropertyValue(PropertyIds.CATALOGNAME.name), schema, table);
+ column = 12;
+ } else {
+ results = connection.getMetaData().getPrimaryKeys(this.table.getPropertyValue(PropertyIds.CATALOGNAME.name), schema, table);
+ column = 6;
+ }
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ while (results.next()) {
+ String name = row.getString(column);
+ if (!hasByName(name)) { // this name wasn't inserted yet so it must be the new one
+ descriptor.setPropertyValue(PropertyIds.NAME.name, name);
+ newName = name;
+ break;
+ }
+ }
+ }
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+ } catch (SQLException sqlException) {
+ }
+ keys.put(newName, OKey.create(newName, isCaseSensitive(), referencedName, keyType, updateRule, deleteRule, new ArrayList<String>(), table));
+ return createObject(newName);
+ } catch (WrappedTargetException wrappedTargetException) {
+ } catch (UnknownPropertyException unknownPropertyException) {
+ } catch (IllegalArgumentException illegalArgumentException) {
+ } catch (IndexOutOfBoundsException indexOutOfBoundsException) {
+ } catch (PropertyVetoException propertyVetoException) {
+ }
+ return null;
+ }
+
+ protected String getKeyRuleString(boolean isUpdate, int rule) {
+ String keyRule = "";
+ switch (rule) {
+ case KeyRule.CASCADE:
+ keyRule = isUpdate ? " ON UPDATE CASCADE " : " ON DELETE CASCADE ";
+ break;
+ case KeyRule.RESTRICT:
+ keyRule = isUpdate ? " ON UPDATE RESTRICT " : " ON DELETE RESTRICT ";
+ break;
+ case KeyRule.SET_NULL:
+ keyRule = isUpdate ? " ON UPDATE SET NULL " : " ON DELETE SET NULL ";
+ break;
+ case KeyRule.SET_DEFAULT:
+ keyRule = isUpdate ? " ON UPDATE SET DEFAULT " : " ON DELETE SET DEFAULT ";
+ break;
+ }
+ return keyRule;
+ }
+
+ @Override
+ public void dropObject(int index, String name) throws SQLException {
+ XConnection connection = table.getConnection();
+ if (connection == null) {
+ return;
+ }
+ try {
+ XPropertySet key = AnyConverter.toObject(XPropertySet.class, getObject(index));
+ String tableName = DbTools.composeTableName(connection.getMetaData(), table,
+ ComposeRule.InTableDefinitions, false, false, true);
+ final int keyType;
+ if (key != null) {
+ keyType = AnyConverter.toInt(key.getPropertyValue(PropertyIds.TYPE.name));
+ } else {
+ keyType = KeyType.PRIMARY;
+ }
+ final String sql;
+ if (keyType == KeyType.PRIMARY) {
+ sql = String.format("ALTER TABLE %s DROP PRIMARY KEY", tableName);
+ } else {
+ sql = String.format("ALTER TABLE %s %s %s", tableName, getDropForeignKey(),
+ DbTools.quoteName(connection.getMetaData().getIdentifierQuoteString(), name));
+ }
+ XStatement statement = null;
+ try {
+ statement = connection.createStatement();
+ statement.execute(sql);
+ } finally {
+ CompHelper.disposeComponent(statement);
+ }
+ } catch (IllegalArgumentException illegalArgumentException) {
+
+ } catch (WrappedTargetException wrappedTargetException) {
+ } catch (UnknownPropertyException unknownPropertyException) {
+ }
+ }
+
+ public String getDropForeignKey() {
+ return "DROP CONSTRAINT";
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OTable.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OTable.java
new file mode 100644
index 000000000000..118d54fa25aa
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OTable.java
@@ -0,0 +1,187 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.container.XNamed;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbcx.XAlterTable;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.XDataDescriptorFactory;
+import com.sun.star.sdbcx.XIndexesSupplier;
+import com.sun.star.sdbcx.XKeysSupplier;
+import com.sun.star.sdbcx.XRename;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public abstract class OTable extends ODescriptor
+ implements XColumnsSupplier, XKeysSupplier, XNamed, XServiceInfo, XDataDescriptorFactory,
+ XIndexesSupplier, XRename, XAlterTable {
+
+ private static String[] services = {
+ "com.sun.star.sdbcx.Table"
+ };
+
+ private XConnection connection;
+ protected String catalogName;
+ protected String schemaName;
+ protected String description;
+ protected String type;
+
+ protected OContainer keys;
+ protected OContainer columns;
+ protected OContainer indexes;
+ protected OContainer tables;
+
+ protected OTable(Object lock, String name, boolean isCaseSensitive, XConnection connection, OContainer tables) {
+ super(lock, name, isCaseSensitive);
+ this.tables = tables;
+ this.connection = connection;
+ registerProperties();
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.CATALOGNAME.name, PropertyIds.CATALOGNAME.id, Type.STRING, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return catalogName;
+
+ }
+ }, null);
+ registerProperty(PropertyIds.SCHEMANAME.name, PropertyIds.SCHEMANAME.id, Type.STRING, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return schemaName;
+
+ }
+ }, null);
+ registerProperty(PropertyIds.DESCRIPTION.name, PropertyIds.DESCRIPTION.id, Type.STRING, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return description;
+
+ }
+ }, null);
+ registerProperty(PropertyIds.TYPE.name, PropertyIds.TYPE.id, Type.STRING, PropertyAttribute.READONLY,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return type;
+
+ }
+ }, null);
+ }
+
+ @Override
+ protected void postDisposing() {
+ super.postDisposing();
+ if (keys != null) {
+ keys.dispose();
+ }
+ if (columns != null) {
+ columns.dispose();
+ }
+ if (indexes != null) {
+ indexes.dispose();
+ }
+ tables = null;
+ }
+
+ private void checkDisposed() {
+ if (bInDispose || bDisposed) {
+ throw new DisposedException();
+ }
+ }
+
+ // XServiceInfo
+
+ @Override
+ public String getImplementationName() {
+ return "com.sun.star.sdbcx.Table";
+ }
+
+ @Override
+ public String[] getSupportedServiceNames() {
+ return services.clone();
+ }
+
+ @Override
+ public boolean supportsService(String serviceName) {
+ for (String service : services) {
+ if (serviceName.equals(service)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // XColumnsSupplier
+
+ @Override
+ public XNameAccess getColumns() {
+ checkDisposed();
+ synchronized (lock) {
+ if (columns == null) {
+ columns = refreshColumns();
+ }
+ return columns;
+ }
+ }
+
+ @Override
+ public XNameAccess getIndexes() {
+ checkDisposed();
+ synchronized (lock) {
+ if (indexes == null) {
+ indexes = refreshIndexes();
+ }
+ return indexes;
+ }
+ }
+
+ @Override
+ public XIndexAccess getKeys() {
+ checkDisposed();
+ synchronized (lock) {
+ if (keys == null) {
+ keys = refreshKeys();
+ }
+ return keys;
+ }
+ }
+
+ public XConnection getConnection() {
+ return connection;
+ }
+
+ protected abstract OContainer refreshColumns();
+ protected abstract OContainer refreshIndexes();
+ protected abstract OContainer refreshKeys();
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OfficeResourceBundle.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OfficeResourceBundle.java
new file mode 100644
index 000000000000..c13dbce8feb5
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/OfficeResourceBundle.java
@@ -0,0 +1,130 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import com.sun.star.lang.NullPointerException;
+import com.sun.star.resource.MissingResourceException;
+import com.sun.star.resource.OfficeResourceLoader;
+import com.sun.star.resource.XResourceBundle;
+import com.sun.star.resource.XResourceBundleLoader;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.XComponentContext;
+
+public class OfficeResourceBundle implements AutoCloseable {
+
+ private XComponentContext context;
+ private String baseName;
+ private boolean haveAttemptedCreate;
+ private XResourceBundle bundle;
+
+
+ /** constructs a resource bundle
+ @param context
+ the component context to operate in
+ @param bundleBaseName
+ the base name of the resource file which should be accessed (*without* the SUPD!)
+ @raises ::com::sun::star::lang::NullPointerException
+ if the given component context is <NULL/>
+ */
+ public OfficeResourceBundle(XComponentContext context, String bundleBaseName) throws NullPointerException {
+ if (context == null) {
+ throw new NullPointerException();
+ }
+ this.context = context;
+ this.baseName = bundleBaseName;
+ this.haveAttemptedCreate = false;
+ }
+
+ @Override
+ public void close() {
+ CompHelper.disposeComponent(bundle);
+ }
+
+ /** loads the string with the given resource id from the resource bundle
+ @param _resourceId
+ the id of the string to load
+ @return
+ the requested resource string. If no string with the given id exists in the resource bundle,
+ an empty string is returned. In a non-product version, an OSL_ENSURE will notify you of this
+ then.
+ */
+ public String loadString( int _resourceId ) {
+ synchronized (this) {
+ String ret = "";
+ if (loadBundle()) {
+ try {
+ Object value = bundle.getByName(getStringResourceKey(_resourceId));
+ ret = AnyConverter.toString(value);
+ } catch (com.sun.star.uno.Exception ex) {
+ }
+ }
+ return ret;
+ }
+ }
+
+ /** determines whether the resource bundle has a string with the given id
+ @param _resourceId
+ the id of the string whose existence is to be checked
+ @return
+ <TRUE/> if and only if a string with the given ID exists in the resource
+ bundle.
+ */
+ public boolean hasString( int _resourceId ) {
+ synchronized (this) {
+ boolean ret = false;
+ if (loadBundle()) {
+ ret = bundle.hasByName(getStringResourceKey(_resourceId));
+ }
+ return ret;
+ }
+ }
+
+ private String getStringResourceKey(int resourceId) {
+ return "string:" + resourceId;
+ }
+
+ private boolean loadBundle() {
+ if (haveAttemptedCreate) {
+ return bundle != null;
+ }
+ haveAttemptedCreate = true;
+
+ try {
+ XResourceBundleLoader loader = OfficeResourceLoader.get(context);
+ try {
+ if (loader == null) {
+ return false;
+ }
+ try {
+ bundle = loader.loadBundle_Default(baseName);
+ } catch (MissingResourceException missingResourceException) {
+ }
+ return bundle != null;
+ } finally {
+ CompHelper.disposeComponent(loader);
+ }
+ } catch (Exception exception) {
+ }
+ return false;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/Resources.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/Resources.java
new file mode 100644
index 000000000000..2b904aba1f76
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/Resources.java
@@ -0,0 +1,66 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+public class Resources {
+ public static final int STR_COMMON_BASE = 1200;
+
+ public static final int STR_STRING_LENGTH_EXCEEDED = (STR_COMMON_BASE + 1);
+ public static final int STR_CANNOT_CONVERT_STRING = (STR_COMMON_BASE + 2);
+ public static final int STR_URI_SYNTAX_ERROR = (STR_COMMON_BASE + 3);
+ public static final int STR_COULD_NOT_LOAD_FILE = (STR_COMMON_BASE + 4);
+ public static final int STR_QUERY_TOO_COMPLEX = (STR_COMMON_BASE + 5);
+ public static final int STR_OPERATOR_TOO_COMPLEX = (STR_COMMON_BASE + 6);
+ public static final int STR_QUERY_INVALID_LIKE_COLUMN = (STR_COMMON_BASE + 7);
+ public static final int STR_QUERY_INVALID_LIKE_STRING = (STR_COMMON_BASE + 8);
+ public static final int STR_QUERY_NOT_LIKE_TOO_COMPLEX = (STR_COMMON_BASE + 9);
+ public static final int STR_QUERY_LIKE_WILDCARD = (STR_COMMON_BASE + 10);
+ public static final int STR_QUERY_LIKE_WILDCARD_MANY = (STR_COMMON_BASE + 11);
+ public static final int STR_INVALID_COLUMNNAME = (STR_COMMON_BASE + 12);
+ public static final int STR_NO_CLASSNAME = (STR_COMMON_BASE + 13);
+ public static final int STR_NO_CLASSNAME_PATH = (STR_COMMON_BASE + 14);
+ public static final int STR_UNKNOWN_PARA_TYPE = (STR_COMMON_BASE + 15);
+ public static final int STR_INVALID_COLUMN_SELECTION = (STR_COMMON_BASE + 16);
+ public static final int STR_PARA_ONLY_PREPARED = (STR_COMMON_BASE + 17);
+ public static final int STR_COLUMN_NOT_UPDATEABLE = (STR_COMMON_BASE + 18);
+ public static final int STR_ROW_ALREADY_DELETED = (STR_COMMON_BASE + 19);
+ public static final int STR_UNKNOWN_COLUMN_TYPE = (STR_COMMON_BASE + 20);
+ public static final int STR_FORMULA_WRONG = (STR_COMMON_BASE + 21);
+ public static final int STR_NO_JAVA = (STR_COMMON_BASE + 22);
+ public static final int STR_NO_RESULTSET = (STR_COMMON_BASE + 23);
+ public static final int STR_NO_ROWCOUNT = (STR_COMMON_BASE + 24);
+ public static final int STR_ERRORMSG_SEQUENCE = (STR_COMMON_BASE + 25);
+ public static final int STR_INVALID_INDEX = (STR_COMMON_BASE + 26);
+ public static final int STR_UNSUPPORTED_FUNCTION = (STR_COMMON_BASE + 27);
+ public static final int STR_UNSUPPORTED_FEATURE = (STR_COMMON_BASE + 28);
+ public static final int STR_UNKNOWN_COLUMN_NAME = (STR_COMMON_BASE + 29);
+ public static final int STR_INVALID_PARA_COUNT = (STR_COMMON_BASE + 30);
+ public static final int STR_PRIVILEGE_NOT_GRANTED = (STR_COMMON_BASE + 31);
+ public static final int STR_PRIVILEGE_NOT_REVOKED = (STR_COMMON_BASE + 32);
+ public static final int STR_INVALID_BOOKMARK = (STR_COMMON_BASE + 33);
+ public static final int STR_NO_ELEMENT_NAME = (STR_COMMON_BASE + 34);
+ public static final int STR_NO_INPUTSTREAM = (STR_COMMON_BASE + 35);
+ public static final int STR_INPUTSTREAM_WRONG_LEN = (STR_COMMON_BASE + 36);
+ public static final int STR_WRONG_PARAM_INDEX = (STR_COMMON_BASE + 37);
+ public static final int STR_NO_CONNECTION_GIVEN = (STR_COMMON_BASE + 38);
+
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/SharedResources.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/SharedResources.java
new file mode 100644
index 000000000000..fa3e3660ba1c
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/SharedResources.java
@@ -0,0 +1,213 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.List;
+
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.commons.lang3.tuple.Pair;
+
+import com.sun.star.lang.NullPointerException;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.uno.XComponentContext;
+
+/**
+ * helper class for accessing resources shared by different libraries
+ * in the connectivity module.
+ */
+public class SharedResources {
+ private static SharedResources instance;
+ private static int referenceCount = 0;
+
+ private OfficeResourceBundle resourceBundle;
+
+ // FIXME: the C++ implementation gets the XComponentContext using ::comphelper::getProcessServiceFactory(), we don't.
+ public synchronized static void registerClient(XComponentContext context) {
+ if (instance == null) {
+ instance = new SharedResources(context);
+ }
+ ++referenceCount;
+ }
+
+ public synchronized static void revokeClient() {
+ if (--referenceCount == 0) {
+ CompHelper.disposeComponent(instance);
+ instance = null;
+ }
+ }
+
+ public synchronized static SharedResources getInstance() {
+ return instance;
+ }
+
+ private SharedResources(XComponentContext context) {
+ try {
+ resourceBundle = new OfficeResourceBundle(context, "cnr");
+ } catch (NullPointerException nullPointerException) {
+ }
+ }
+
+ private int substitute( MutableObject<String> _inout_rString,
+ String sPattern, String _rReplace ) {
+ int nOccurences = 0;
+ String string = _inout_rString.getValue();
+ int nIndex = 0;
+ while ( ( nIndex = string.indexOf( sPattern ) ) > -1 )
+ {
+ ++nOccurences;
+ string = string.substring(0, nIndex) +
+ _rReplace + string.substring(nIndex + sPattern.length());
+ }
+ _inout_rString.setValue(string);
+ return nOccurences;
+ }
+
+
+ /** loads a string from the shared resource file
+ @param _nResId
+ the resource ID of the string
+ @return
+ the string from the resource file
+ */
+ public String
+ getResourceString(
+ int _nResId
+ ) {
+ if (resourceBundle == null) {
+ return "";
+ }
+ return resourceBundle.loadString(_nResId);
+ }
+
+ /** loads a string from the shared resource file, and replaces
+ a given ASCII pattern with a given string
+
+ @param _nResId
+ the resource ID of the string to load
+ @param _pAsciiPatternToReplace
+ the ASCII string which is to search in the string. Must not be <NULL/>.
+ @param _rStringToSubstitute
+ the String which should substitute the ASCII pattern.
+
+ @return
+ the string from the resource file, with applied string substitution
+ */
+ public String
+ getResourceStringWithSubstitution(
+ int _nResId,
+ String _pAsciiPatternToReplace,
+ String _rStringToSubstitute
+ ) {
+ MutableObject<String> string = new MutableObject<>(getResourceString(_nResId));
+ substitute(string, _pAsciiPatternToReplace, _rStringToSubstitute);
+ return string.getValue();
+ }
+
+ /** loads a string from the shared resource file, and replaces
+ a given ASCII pattern with a given string
+
+ @param _nResId
+ the resource ID of the string to load
+ @param _pAsciiPatternToReplace1
+ the ASCII string (1) which is to search in the string. Must not be <NULL/>.
+ @param _rStringToSubstitute1
+ the String which should substitute the ASCII pattern (1)
+ @param _pAsciiPatternToReplace2
+ the ASCII string (2) which is to search in the string. Must not be <NULL/>.
+ @param _rStringToSubstitute2
+ the String which should substitute the ASCII pattern (2)
+
+ @return
+ the string from the resource file, with applied string substitution
+ */
+ public String
+ getResourceStringWithSubstitution(
+ int _nResId,
+ String _pAsciiPatternToReplace1,
+ String _rStringToSubstitute1,
+ String _pAsciiPatternToReplace2,
+ String _rStringToSubstitute2
+ ) {
+ MutableObject<String> string = new MutableObject<>(getResourceString(_nResId));
+ substitute(string, _pAsciiPatternToReplace1, _rStringToSubstitute1);
+ substitute(string, _pAsciiPatternToReplace2, _rStringToSubstitute2);
+ return string.getValue();
+ }
+
+ /** loads a string from the shared resource file, and replaces
+ a given ASCII pattern with a given string
+
+ @param _nResId
+ the resource ID of the string to load
+ @param _pAsciiPatternToReplace1
+ the ASCII string (1) which is to search in the string. Must not be <NULL/>.
+ @param _rStringToSubstitute1
+ the String which should substitute the ASCII pattern (1)
+ @param _pAsciiPatternToReplace2
+ the ASCII string (2) which is to search in the string. Must not be <NULL/>.
+ @param _rStringToSubstitute2
+ the String which should substitute the ASCII pattern (2)
+ @param _pAsciiPatternToReplace3
+ the ASCII string (3) which is to search in the string. Must not be <NULL/>.
+ @param _rStringToSubstitute3
+ the String which should substitute the ASCII pattern (3)
+
+ @return
+ the string from the resource file, with applied string substitution
+ */
+ public String
+ getResourceStringWithSubstitution(
+ int _nResId,
+ String _pAsciiPatternToReplace1,
+ String _rStringToSubstitute1,
+ String _pAsciiPatternToReplace2,
+ String _rStringToSubstitute2,
+ String _pAsciiPatternToReplace3,
+ String _rStringToSubstitute3
+ ) {
+ MutableObject<String> string = new MutableObject<>(getResourceString(_nResId));
+ substitute(string, _pAsciiPatternToReplace1, _rStringToSubstitute1);
+ substitute(string, _pAsciiPatternToReplace2, _rStringToSubstitute2);
+ substitute(string, _pAsciiPatternToReplace3, _rStringToSubstitute3);
+ return string.getValue();
+ }
+
+ /** loads a string from the shared resource file, and replaces a given ASCII pattern with a given string
+
+ @param _nResId
+ the resource ID of the string to load
+ @param _aStringToSubstitutes
+ A list of substitutions.
+
+ @return
+ the string from the resource file, with applied string substitution
+ */
+ public String
+ getResourceStringWithSubstitution( int _nResId,
+ List<Pair<String,String>> patternsAndSubstitutes) {
+ MutableObject<String> string = new MutableObject<>(getResourceString(_nResId));
+ for (Pair<String,String> pair : patternsAndSubstitutes) {
+ substitute(string, pair.getLeft(), pair.getRight());
+ }
+ return string.getValue();
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/SqlTableHelper.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/SqlTableHelper.java
new file mode 100644
index 000000000000..ba1db755947c
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/SqlTableHelper.java
@@ -0,0 +1,261 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XDatabaseMetaData;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbcx.KeyType;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.util.ComposeRule;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+import com.sun.star.sdbcx.comp.postgresql.util.Osl;
+import com.sun.star.uno.Any;
+import com.sun.star.uno.UnoRuntime;
+
+public class SqlTableHelper {
+ public static class ColumnDescription {
+ public String columnName;
+ public int type;
+ public String typeName;
+ public int columnSize;
+ public int decimalDigits;
+ public int nullable;
+ public String remarks;
+ public String defaultValue;
+ public int ordinalPosition;
+ }
+
+ private static class KeyProperties {
+ ArrayList<String> columnNames = new ArrayList<>();
+ String referencedTable;
+ int type;
+ int updateRule;
+ int deleteRule;
+
+ KeyProperties(String referencedTable, int type, int updateRule, int deleteRule) {
+ this.referencedTable = referencedTable;
+ this.type = type;
+ this.updateRule = updateRule;
+ this.deleteRule = deleteRule;
+ }
+ }
+
+ public List<ColumnDescription> readColumns(XDatabaseMetaData metadata, String catalog, String schema, String table) throws SQLException {
+ String catalogName = catalog;
+ if (catalog.isEmpty()) {
+ catalogName = null;
+ }
+
+ XResultSet results = metadata.getColumns(catalogName, schema, table, "%");
+ List<ColumnDescription> columnDescriptions = collectColumnDescriptions(results);
+ sanitizeColumnDescriptions(columnDescriptions);
+
+ List<ColumnDescription> columnsByOrdinal = new ArrayList<>(columnDescriptions);
+ for (ColumnDescription columnDescription : columnDescriptions) {
+ columnsByOrdinal.set(columnDescription.ordinalPosition - 1, columnDescription);
+ }
+ return columnsByOrdinal;
+ }
+
+ private List<ColumnDescription> collectColumnDescriptions(XResultSet results) throws SQLException {
+ List<ColumnDescription> columns = new ArrayList<>();
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ while (results.next()) {
+ ColumnDescription columnDescription = new ColumnDescription();
+ columnDescription.columnName = row.getString(4);
+ columnDescription.type = row.getInt(5);
+ columnDescription.typeName = row.getString(6);
+ columnDescription.columnSize = row.getInt(7);
+ columnDescription.decimalDigits = row.getInt(9);
+ columnDescription.nullable = row.getInt(11);
+ columnDescription.remarks = row.getString(12);
+ columnDescription.defaultValue = row.getString(13);
+ columnDescription.ordinalPosition = row.getInt(17);
+ columns.add(columnDescription);
+ }
+ return columns;
+ }
+
+ private void sanitizeColumnDescriptions(List<ColumnDescription> columnDescriptions) {
+ if (columnDescriptions.isEmpty()) {
+ return;
+ }
+ Set<Integer> usedOrdinals = new TreeSet<>();
+ int maxOrdinal = Integer.MIN_VALUE;
+ for (ColumnDescription columnDescription : columnDescriptions) {
+ usedOrdinals.add(columnDescription.ordinalPosition);
+ if (maxOrdinal < columnDescription.ordinalPosition) {
+ maxOrdinal = columnDescription.ordinalPosition;
+ }
+ }
+ // we need to have as many different ordinals as we have different columns
+ boolean hasDuplicates = usedOrdinals.size() != columnDescriptions.size();
+ // and it needs to be a continuous range
+ boolean hasGaps = (maxOrdinal - usedOrdinals.iterator().next() + 1) != columnDescriptions.size();
+ // if that's not the case, normalize it
+ Osl.ensure(!hasDuplicates && !hasGaps, "database provided invalid ORDINAL_POSITION values!");
+ // what's left is that the range might not be from 1 to <column count>, but for instance
+ // 0 to <column count>-1.
+ int offset = usedOrdinals.iterator().next() - 1;
+ for (ColumnDescription columnDescription : columnDescriptions) {
+ columnDescription.ordinalPosition -= offset;
+ }
+ }
+
+ public Map<String, OKey> readKeys(XDatabaseMetaData metadata, String catalogName, String schemaName, String tableName,
+ boolean isCaseSensitive, OTable table) throws SQLException {
+ Map<String, OKey> keys = new TreeMap<>();
+ OKey primaryKey = readPrimaryKey(metadata, catalogName, schemaName, tableName, isCaseSensitive, table);
+ keys.put(primaryKey.getName(), primaryKey);
+ readForeignKeys(metadata, catalogName, schemaName, tableName, isCaseSensitive, keys, table);
+ return keys;
+ }
+
+ private OKey readPrimaryKey(XDatabaseMetaData metadata,
+ String catalogName, String schemaName, String tableName, boolean isCaseSensitive, OTable table) throws SQLException {
+ Object catalog = Any.VOID;
+ if (!catalogName.isEmpty()) {
+ catalog = catalogName;
+ }
+ XResultSet results = null;
+ try {
+ ArrayList<String> columns = new ArrayList<>();
+ boolean alreadyFetched = false;
+ String pkName = "";
+ OKey key = null;
+ results = metadata.getPrimaryKeys(catalog, schemaName, tableName);
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ while (results.next()) {
+ String columnName = row.getString(4);
+ columns.add(columnName);
+ if (!alreadyFetched) {
+ alreadyFetched = true;
+ pkName = row.getString(6);
+ }
+ }
+ key = OKey.create(pkName, isCaseSensitive, "", KeyType.PRIMARY, 0, 0, columns, table);
+ }
+ return key;
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+ }
+
+ private void readForeignKeys(XDatabaseMetaData metadata,
+ String catalogName, String schemaName, String tableName, boolean isCaseSensitive, Map<String, OKey> keys, OTable table) throws SQLException {
+ Object catalog = Any.VOID;
+ if (!catalogName.isEmpty()) {
+ catalog = catalogName;
+ }
+ XResultSet results = null;
+ try {
+ results = metadata.getImportedKeys(catalog, schemaName, tableName);
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ if (row != null) {
+ String oldFkName = "";
+ KeyProperties keyProperties = null;
+ while (results.next()) {
+ String catalogReturned = row.getString(1);
+ if (row.wasNull()) {
+ catalogReturned = "";
+ }
+ String schemaReturned = row.getString(2);
+ String nameReturned = row.getString(3);
+
+ String foreignKeyColumn = row.getString(8);
+ int updateRule = row.getInt(10);
+ int deleteRule = row.getInt(11);
+ String fkName = row.getString(12);
+
+ if (!row.wasNull() && !fkName.isEmpty()) {
+ if (!oldFkName.equals(fkName)) {
+ if (keyProperties != null) {
+ OKey key = OKey.create(oldFkName, isCaseSensitive, keyProperties.referencedTable, keyProperties.type,
+ keyProperties.updateRule, keyProperties.deleteRule, keyProperties.columnNames, table);
+ keys.put(oldFkName, key);
+ }
+ String referencedName = DbTools.composeTableName(metadata, catalogReturned, schemaReturned, nameReturned,
+ false, ComposeRule.InDataManipulation);
+ keyProperties = new KeyProperties(referencedName, KeyType.FOREIGN, updateRule, deleteRule);
+ keyProperties.columnNames.add(foreignKeyColumn);
+ oldFkName = fkName;
+ } else {
+ if (keyProperties != null) {
+ keyProperties.columnNames.add(foreignKeyColumn);
+ }
+ }
+ }
+ }
+ if (keyProperties != null) {
+ OKey key = OKey.create(oldFkName, isCaseSensitive, keyProperties.referencedTable, keyProperties.type,
+ keyProperties.updateRule, keyProperties.deleteRule, keyProperties.columnNames, table);
+ keys.put(oldFkName, key);
+ }
+ }
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+ }
+
+ public ArrayList<String> readIndexes(XDatabaseMetaData metadata, String catalogName, String schemaName, String tableName, OTable table) throws SQLException {
+ Object catalog = Any.VOID;
+ if (!catalogName.isEmpty()) {
+ catalog = catalogName;
+ }
+ ArrayList<String> names = new ArrayList<>();
+ XResultSet results = null;
+ try {
+ results = metadata.getIndexInfo(catalog, schemaName, tableName, false, false);
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ String catalogSep = metadata.getCatalogSeparator();
+ String previousRoundName = "";
+ while (results.next()) {
+ String name = row.getString(5);
+ if (!name.isEmpty()) {
+ name += catalogSep;
+ }
+ name += row.getString(6);
+ if (!name.isEmpty()) {
+ // don't insert the name if the last one we inserted was the same
+ if (!previousRoundName.equals(name)) {
+ names.add(name);
+ }
+ }
+ }
+ }
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+ return names;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxColumnDescriptor.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxColumnDescriptor.java
new file mode 100644
index 000000000000..109940d80d9e
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxColumnDescriptor.java
@@ -0,0 +1,194 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertySetter;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.ODescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class SdbcxColumnDescriptor extends ODescriptor {
+ protected int type;
+ protected String typeName;
+ protected int precision;
+ protected int scale;
+ protected int isNullable;
+ protected boolean isAutoIncrement;
+ protected boolean isRowVersion;
+ protected String description;
+ protected String defaultValue;
+ protected boolean isCurrency;
+
+ protected SdbcxColumnDescriptor(Object lock, boolean isCaseSensitive) {
+ super(lock, "", isCaseSensitive, false);
+ registerProperties();
+ }
+
+ public static SdbcxColumnDescriptor create(boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new SdbcxColumnDescriptor(lock, isCaseSensitive);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.TYPE.name, PropertyIds.TYPE.id, Type.LONG, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return type;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ type = (int) value;
+ }
+ });
+ registerProperty(PropertyIds.TYPENAME.name, PropertyIds.TYPENAME.id, Type.STRING, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return typeName;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ typeName = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.PRECISION.name, PropertyIds.PRECISION.id, Type.LONG, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return precision;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ precision = (Integer) value;
+ }
+ });
+ registerProperty(PropertyIds.SCALE.name, PropertyIds.SCALE.id, Type.LONG, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return scale;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ scale = (Integer) value;
+ }
+ });
+ registerProperty(PropertyIds.ISNULLABLE.name, PropertyIds.ISNULLABLE.id, Type.LONG, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isNullable;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isNullable = (Integer) value;
+ }
+ });
+ registerProperty(PropertyIds.ISAUTOINCREMENT.name, PropertyIds.ISAUTOINCREMENT.id, Type.BOOLEAN, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isAutoIncrement;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isAutoIncrement = (Boolean) value;
+ }
+ });
+ registerProperty(PropertyIds.ISROWVERSION.name, PropertyIds.ISROWVERSION.id, Type.BOOLEAN, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isRowVersion;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isRowVersion = (Boolean) value;
+ }
+ });
+ registerProperty(PropertyIds.DESCRIPTION.name, PropertyIds.DESCRIPTION.id, Type.STRING, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return description;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ description = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.DEFAULTVALUE.name, PropertyIds.DEFAULTVALUE.id, Type.STRING, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return defaultValue;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ defaultValue = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.ISCURRENCY.name, PropertyIds.ISCURRENCY.id, Type.BOOLEAN, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isCurrency;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isCurrency = (Boolean) value;
+ }
+ });
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxColumnDescriptorContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxColumnDescriptorContainer.java
new file mode 100644
index 000000000000..25ae2a597b4d
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxColumnDescriptorContainer.java
@@ -0,0 +1,36 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.beans.XPropertySet;
+
+public class SdbcxColumnDescriptorContainer extends SdbcxDescriptorContainer {
+
+ public SdbcxColumnDescriptorContainer(Object lock, boolean isCaseSensitive) {
+ super(lock, isCaseSensitive);
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxColumnDescriptor.create(isCaseSensitive());
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxDescriptorContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxDescriptorContainer.java
new file mode 100644
index 000000000000..76d2859b715a
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxDescriptorContainer.java
@@ -0,0 +1,59 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import java.util.Collections;
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OContainer;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.Resources;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.SharedResources;
+import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState;
+
+public abstract class SdbcxDescriptorContainer extends OContainer {
+ public SdbcxDescriptorContainer(Object lock, boolean isCaseSensitive) {
+ super(lock, isCaseSensitive, Collections.<String>emptyList());
+ }
+
+ @Override
+ public XPropertySet createObject(String name) throws SQLException {
+ // This should never be called. DescriptorContainer always starts off empty,
+ // and only grows as a result of appending.
+ String error = SharedResources.getInstance().getResourceString(
+ Resources.STR_ERRORMSG_SEQUENCE);
+ throw new SQLException(error, this, StandardSQLState.SQL_FUNCTION_SEQUENCE_ERROR.text(), 0, null);
+ }
+
+ @Override
+ public void dropObject(int index, String name) throws SQLException {
+ }
+
+ @Override
+ public void impl_refresh() {
+ }
+
+ @Override
+ public XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException {
+ return cloneDescriptor(descriptor);
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexColumnDescriptor.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexColumnDescriptor.java
new file mode 100644
index 000000000000..101257153c49
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexColumnDescriptor.java
@@ -0,0 +1,58 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertySetter;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class SdbcxIndexColumnDescriptor extends SdbcxColumnDescriptor {
+ protected boolean isAscending;
+
+ protected SdbcxIndexColumnDescriptor(Object lock, boolean isCaseSensitive) {
+ super(lock, isCaseSensitive);
+ registerProperties();
+ }
+
+ public static SdbcxIndexColumnDescriptor create(boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new SdbcxIndexColumnDescriptor(lock, isCaseSensitive);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.ISASCENDING.name, PropertyIds.ISASCENDING.id, Type.BOOLEAN, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isAscending;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isAscending = (boolean) value;
+ }
+ });
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexColumnDescriptorContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexColumnDescriptorContainer.java
new file mode 100644
index 000000000000..f7a5e5e945a1
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexColumnDescriptorContainer.java
@@ -0,0 +1,35 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.beans.XPropertySet;
+
+public class SdbcxIndexColumnDescriptorContainer extends SdbcxDescriptorContainer {
+ public SdbcxIndexColumnDescriptorContainer(Object lock, boolean isCaseSensitive) {
+ super(lock, isCaseSensitive);
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxIndexColumnDescriptor.create(isCaseSensitive());
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexDescriptor.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexDescriptor.java
new file mode 100644
index 000000000000..139610fd31e9
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexDescriptor.java
@@ -0,0 +1,94 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertySetter;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.ODescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class SdbcxIndexDescriptor extends ODescriptor implements XColumnsSupplier {
+ protected String catalog = "";
+ protected boolean isUnique;
+ protected boolean isClustered;
+
+ private SdbcxIndexColumnDescriptorContainer columns;
+
+ protected SdbcxIndexDescriptor(Object lock, boolean isCaseSensitive) {
+ super(lock, "", isCaseSensitive, false);
+ columns = new SdbcxIndexColumnDescriptorContainer(this.lock, isCaseSensitive());
+ registerProperties();
+ }
+
+ public static SdbcxIndexDescriptor create(boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new SdbcxIndexDescriptor(lock, isCaseSensitive);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.CATALOG.name, PropertyIds.CATALOG.id, Type.STRING, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return catalog;
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ catalog = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.ISUNIQUE.name, PropertyIds.ISUNIQUE.id, Type.BOOLEAN, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isUnique;
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isUnique = (boolean) value;
+ }
+ });
+ registerProperty(PropertyIds.ISCLUSTERED.name, PropertyIds.ISCLUSTERED.id, Type.BOOLEAN, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return isClustered;
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ isClustered = (boolean) value;
+ }
+ });
+ }
+
+ public SdbcxIndexColumnDescriptorContainer getColumns() {
+ return columns;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexDescriptorContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexDescriptorContainer.java
new file mode 100644
index 000000000000..df169dc0f50a
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxIndexDescriptorContainer.java
@@ -0,0 +1,44 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+
+public class SdbcxIndexDescriptorContainer extends SdbcxDescriptorContainer {
+ public SdbcxIndexDescriptorContainer(Object lock, boolean isCaseSensitive) {
+ super(lock, isCaseSensitive);
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxIndexDescriptor.create(isCaseSensitive());
+ }
+
+ @Override
+ public XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException {
+ XPropertySet newDescriptor = cloneDescriptor(descriptor);
+ DbTools.cloneDescriptorColumns(descriptor, newDescriptor);
+ return newDescriptor;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyColumnDescriptor.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyColumnDescriptor.java
new file mode 100644
index 000000000000..6ddb4d205db3
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyColumnDescriptor.java
@@ -0,0 +1,58 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertySetter;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class SdbcxKeyColumnDescriptor extends SdbcxColumnDescriptor {
+ protected String relatedColumn;
+
+ protected SdbcxKeyColumnDescriptor(Object lock, boolean isCaseSensitive) {
+ super(lock, isCaseSensitive);
+ registerProperties();
+ }
+
+ public static SdbcxKeyColumnDescriptor create(boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new SdbcxKeyColumnDescriptor(lock, isCaseSensitive);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.RELATEDCOLUMN.name, PropertyIds.RELATEDCOLUMN.id, Type.STRING, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return relatedColumn;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ relatedColumn = (String) value;
+ }
+ });
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyColumnDescriptorContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyColumnDescriptorContainer.java
new file mode 100644
index 000000000000..bb3aed4bbb1c
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyColumnDescriptorContainer.java
@@ -0,0 +1,35 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.beans.XPropertySet;
+
+public class SdbcxKeyColumnDescriptorContainer extends SdbcxDescriptorContainer {
+ public SdbcxKeyColumnDescriptorContainer(Object lock, boolean isCaseSensitive) {
+ super(lock, isCaseSensitive);
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxKeyColumnDescriptor.create(isCaseSensitive());
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyDescriptor.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyDescriptor.java
new file mode 100644
index 000000000000..262cc8724b27
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyDescriptor.java
@@ -0,0 +1,113 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.container.XNameAccess;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertySetter;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.ODescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class SdbcxKeyDescriptor extends ODescriptor implements XColumnsSupplier {
+ protected int type;
+ protected String referencedTable;
+ protected int updateRule;
+ protected int deleteRule;
+
+ private SdbcxKeyColumnDescriptorContainer columns;
+
+ protected SdbcxKeyDescriptor(Object lock, boolean isCaseSensitive) {
+ super(lock, "", isCaseSensitive, false);
+ registerProperties();
+ columns = new SdbcxKeyColumnDescriptorContainer(this.lock, isCaseSensitive());
+ }
+
+ public static SdbcxKeyDescriptor create(boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new SdbcxKeyDescriptor(lock, isCaseSensitive);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.TYPE.name, PropertyIds.TYPE.id, Type.LONG, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return type;
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ type = (int) value;
+ }
+ });
+ registerProperty(PropertyIds.REFERENCEDTABLE.name, PropertyIds.REFERENCEDTABLE.id, Type.STRING, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return referencedTable;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ referencedTable = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.UPDATERULE.name, PropertyIds.UPDATERULE.id, Type.LONG, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return updateRule;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ updateRule = (int) value;
+ }
+ });
+ registerProperty(PropertyIds.DELETERULE.name, PropertyIds.DELETERULE.id, Type.LONG, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return deleteRule;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ deleteRule = (int) value;
+ }
+ });
+ }
+
+ @Override
+ public XNameAccess getColumns() {
+ return columns;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyDescriptorContainer.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyDescriptorContainer.java
new file mode 100644
index 000000000000..e387ac49a3ff
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxKeyDescriptorContainer.java
@@ -0,0 +1,44 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
+
+public class SdbcxKeyDescriptorContainer extends SdbcxDescriptorContainer {
+ public SdbcxKeyDescriptorContainer(Object lock, boolean isCaseSensitive) {
+ super(lock, isCaseSensitive);
+ }
+
+ @Override
+ public XPropertySet createDescriptor() {
+ return SdbcxKeyDescriptor.create(isCaseSensitive());
+ }
+
+ @Override
+ public XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException {
+ XPropertySet newDescriptor = cloneDescriptor(descriptor);
+ DbTools.cloneDescriptorColumns(descriptor, newDescriptor);
+ return newDescriptor;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxTableDescriptor.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxTableDescriptor.java
new file mode 100644
index 000000000000..65d08a893e83
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/sdbcx/descriptors/SdbcxTableDescriptor.java
@@ -0,0 +1,109 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors;
+
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.XKeysSupplier;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertyGetter;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.PropertySetAdapter.PropertySetter;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OContainer;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.ODescriptor;
+import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
+import com.sun.star.uno.Type;
+
+public class SdbcxTableDescriptor extends ODescriptor implements XColumnsSupplier, XKeysSupplier {
+ protected String catalogName;
+ protected String schemaName;
+ protected String description;
+
+ private OContainer columns;
+ private OContainer keys;
+
+ protected SdbcxTableDescriptor(Object lock, boolean isCaseSensitive) {
+ super(lock, "", isCaseSensitive, false);
+ columns = new SdbcxColumnDescriptorContainer(this.lock, isCaseSensitive());
+ keys = new SdbcxKeyDescriptorContainer(this.lock, isCaseSensitive());
+ registerProperties();
+ }
+
+ public static SdbcxTableDescriptor create(boolean isCaseSensitive) {
+ final Object lock = new Object();
+ return new SdbcxTableDescriptor(lock, isCaseSensitive);
+ }
+
+ private void registerProperties() {
+ registerProperty(PropertyIds.CATALOGNAME.name, PropertyIds.CATALOGNAME.id, Type.STRING, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return catalogName;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ catalogName = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.SCHEMANAME.name, PropertyIds.SCHEMANAME.id, Type.STRING, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return schemaName;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ schemaName = (String) value;
+ }
+ });
+ registerProperty(PropertyIds.DESCRIPTION.name, PropertyIds.DESCRIPTION.id, Type.STRING, (short)0,
+ new PropertyGetter() {
+ @Override
+ public Object getValue() {
+ return description;
+
+ }
+ },
+ new PropertySetter() {
+ @Override
+ public void setValue(Object value) {
+ description = (String) value;
+ }
+ });
+ }
+
+ @Override
+ public XNameAccess getColumns() {
+ return columns;
+ }
+
+ @Override
+ public XIndexAccess getKeys() {
+ return keys;
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ComposeRule.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ComposeRule.java
new file mode 100644
index 000000000000..5fee9f038e52
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ComposeRule.java
@@ -0,0 +1,31 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+public enum ComposeRule {
+ InTableDefinitions,
+ InIndexDefinitions,
+ InDataManipulation,
+ InProcedureCalls,
+ InPrivilegeDefinitions,
+ Complete
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DBTypeConversion.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DBTypeConversion.java
new file mode 100644
index 000000000000..943c78a15747
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DBTypeConversion.java
@@ -0,0 +1,426 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+import java.util.StringTokenizer;
+
+import com.sun.star.util.Date;
+import com.sun.star.util.DateTime;
+import com.sun.star.util.Time;
+
+public class DBTypeConversion {
+ private static final int MAX_DAYS = 3636532;
+ private static Date standardDate = new Date((short)1, (short)1, (short)1900);
+ private static int aDaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ private static final double fMilliSecondsPerDay = 86400000.0;
+
+ public static double safeParseDouble(String value) {
+ try {
+ return Double.parseDouble(value);
+ } catch (NumberFormatException numberFormatException) {
+ return 0.0;
+ }
+ }
+
+ public static float safeParseFloat(String value) {
+ try {
+ return Float.parseFloat(value);
+ } catch (NumberFormatException numberFormatException) {
+ return 0.0f;
+ }
+ }
+
+ public static int safeParseInt(String value) {
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException numberFormatException) {
+ return 0;
+ }
+ }
+
+ public static long safeParseLong(String value) {
+ try {
+ return Long.parseLong(value);
+ } catch (NumberFormatException numberFormatException) {
+ return 0;
+ }
+ }
+
+ public static float unsignedLongToFloat(long value) {
+ float f = value & 0x7fffFFFFffffFFFFL;
+ if (value < 0) {
+ f += 0x1p63f;
+ }
+ return f;
+ }
+
+ public static double unsignedLongToDouble(long value) {
+ double d = value & 0x7fffFFFFffffFFFFL;
+ if (value < 0) {
+ d += 0x1p63f;
+ }
+ return d;
+ }
+
+ public static void addDays(int nDays, Date _rDate) {
+ int nTempDays = implRelativeToAbsoluteNull( _rDate );
+
+ nTempDays += nDays;
+ if ( nTempDays > MAX_DAYS )
+ {
+ _rDate.Day = 31;
+ _rDate.Month = 12;
+ _rDate.Year = 9999;
+ }
+ else if ( nTempDays <= 0 )
+ {
+ _rDate.Day = 1;
+ _rDate.Month = 1;
+ _rDate.Year = 00;
+ }
+ else
+ implBuildFromRelative( nTempDays, _rDate );
+ }
+
+ public static void subDays(int nDays, Date _rDate) {
+ int nTempDays = implRelativeToAbsoluteNull( _rDate );
+
+ nTempDays -= nDays;
+ if ( nTempDays > MAX_DAYS )
+ {
+ _rDate.Day = 31;
+ _rDate.Month = 12;
+ _rDate.Year = 9999;
+ }
+ else if ( nTempDays <= 0 )
+ {
+ _rDate.Day = 1;
+ _rDate.Month = 1;
+ _rDate.Year = 00;
+ }
+ else
+ implBuildFromRelative( nTempDays, _rDate );
+ }
+
+ public static int getMsFromTime(final Time rVal) {
+ int nHour = rVal.Hours;
+ int nMin = rVal.Minutes;
+ int nSec = rVal.Seconds;
+ int n100Sec = rVal.HundredthSeconds;
+
+ return ((nHour*3600000)+(nMin*60000)+(nSec*1000)+(n100Sec*10));
+ }
+
+ public static Date getStandardDate() {
+ return standardDate;
+ }
+
+ private static int implDaysInMonth(int _nMonth, int _nYear) {
+ if (_nMonth != 2)
+ return aDaysInMonth[_nMonth-1];
+ else {
+ if (implIsLeapYear(_nYear))
+ return aDaysInMonth[_nMonth-1] + 1;
+ else
+ return aDaysInMonth[_nMonth-1];
+ }
+ }
+
+ private static void implBuildFromRelative( int nDays, Date date ) {
+ int nTempDays;
+ int i = 0;
+ boolean bCalc;
+
+ do {
+ nTempDays = nDays;
+ date.Year = (short)((nTempDays / 365) - i);
+ nTempDays -= (date.Year-1) * 365;
+ nTempDays -= ((date.Year-1) / 4) - ((date.Year-1) / 100) + ((date.Year-1) / 400);
+ bCalc = false;
+ if ( nTempDays < 1 )
+ {
+ i++;
+ bCalc = true;
+ }
+ else
+ {
+ if ( nTempDays > 365 )
+ {
+ if ( (nTempDays != 366) || !implIsLeapYear( date.Year ) )
+ {
+ i--;
+ bCalc = true;
+ }
+ }
+ }
+ }
+ while ( bCalc );
+
+ date.Month = 1;
+ while ( nTempDays > implDaysInMonth( date.Month, date.Year ) )
+ {
+ nTempDays -= implDaysInMonth( date.Month, date.Year );
+ date.Month++;
+ }
+ date.Day = (short)nTempDays;
+ }
+
+ private static boolean implIsLeapYear(int _nYear) {
+ return ( ( ((_nYear % 4) == 0)
+ && ((_nYear % 100) != 0)
+ )
+ )
+ || ((_nYear % 400) == 0)
+ ;
+ }
+
+
+ private static int implRelativeToAbsoluteNull(final Date _rDate) {
+ int nDays = 0;
+
+ // ripped this code from the implementation of tools::Date
+ int nNormalizedYear = _rDate.Year - 1;
+ nDays = nNormalizedYear * 365;
+ // leap years
+ nDays += (nNormalizedYear / 4) - (nNormalizedYear / 100) + (nNormalizedYear / 400);
+
+ for (int i = 1; i < _rDate.Month; ++i)
+ nDays += implDaysInMonth(i, _rDate.Year);
+
+ nDays += _rDate.Day;
+ return nDays;
+ }
+
+ public static int toDays(Date rVal) {
+ return toDays(rVal, getStandardDate());
+ }
+
+ public static int toDays(Date rVal, Date rNullDate) {
+ return implRelativeToAbsoluteNull(rVal) - implRelativeToAbsoluteNull(rNullDate);
+ }
+
+ public static double toDouble(Date rVal) {
+ return toDouble(rVal, getStandardDate());
+ }
+
+ public static double toDouble(Date rVal, Date _rNullDate) {
+ return (double)toDays(rVal, _rNullDate);
+ }
+
+ public static double toDouble(DateTime _rVal) {
+ return toDouble(_rVal, getStandardDate());
+ }
+
+ public static double toDouble(DateTime _rVal, Date _rNullDate) {
+ long nTime = toDays(new Date(_rVal.Day, _rVal.Month, _rVal.Year), _rNullDate);
+ Time aTimePart = new Time();
+
+ aTimePart.Hours = _rVal.Hours;
+ aTimePart.Minutes = _rVal.Minutes;
+ aTimePart.Seconds = _rVal.Seconds;
+ aTimePart.HundredthSeconds = _rVal.HundredthSeconds;
+
+ return ((double)nTime) + toDouble(aTimePart);
+ }
+
+ public static double toDouble(Time rVal) {
+ return (double)getMsFromTime(rVal) / fMilliSecondsPerDay;
+ }
+
+ public static Date toDate(double dVal) {
+ return toDate(dVal, getStandardDate());
+ }
+
+ public static Date toDate(double dVal, Date _rNullDate) {
+ Date aRet = _rNullDate;
+
+ if (dVal >= 0)
+ addDays((int)dVal,aRet);
+ else
+ subDays((int)(-dVal),aRet);
+ // x -= (sal_uInt32)(-nDays);
+
+ return aRet;
+ }
+
+ public static Date toDate(String value) {
+ String[] tokens = value.split("-");
+
+ short nYear = 0,
+ nMonth = 0,
+ nDay = 0;
+ if (tokens.length > 0) {
+ nYear = (short)safeParseInt(tokens[0]);
+ }
+ if (tokens.length > 1) {
+ nMonth = (short)safeParseInt(tokens[1]);
+ }
+ if (tokens.length > 2) {
+ nDay = (short)safeParseInt(tokens[2]);
+ }
+
+ return new Date(nDay,nMonth,nYear);
+ }
+
+ public static DateTime toDateTime(double dVal) {
+ return toDateTime(dVal, getStandardDate());
+ }
+
+ public static DateTime toDateTime(double dVal, Date _rNullDate) {
+ Date aDate = toDate(dVal, _rNullDate);
+ Time aTime = toTime(dVal);
+
+ DateTime xRet = new DateTime();
+
+ xRet.Day = aDate.Day;
+ xRet.Month = aDate.Month;
+ xRet.Year = aDate.Year;
+
+ xRet.HundredthSeconds = aTime.HundredthSeconds;
+ xRet.Minutes = aTime.Minutes;
+ xRet.Seconds = aTime.Seconds;
+ xRet.Hours = aTime.Hours;
+
+
+ return xRet;
+ }
+
+ public static DateTime toDateTime(String _sSQLString) {
+ // the date part
+ int nSeparation = _sSQLString.indexOf( ' ' );
+ String dateString;
+ String timeString = "";
+ if (nSeparation >= 0) {
+ dateString = _sSQLString.substring(0, nSeparation);
+ timeString = _sSQLString.substring(nSeparation + 1);
+ } else {
+ dateString = _sSQLString;
+ }
+ Date aDate = toDate(dateString);
+ Time aTime = new Time();
+
+ if ( -1 != nSeparation )
+ aTime = toTime( timeString );
+
+ return new DateTime(aTime.HundredthSeconds,aTime.Seconds,aTime.Minutes,aTime.Hours,aDate.Day,aDate.Month,aDate.Year);
+ }
+
+ public static Time toTime(int _nVal) {
+ Time aReturn = new Time();
+ aReturn.Hours = (short)(((int)(_nVal >= 0 ? _nVal : _nVal*-1)) / 1000000);
+ aReturn.Minutes = (short)((((int)(_nVal >= 0 ? _nVal : _nVal*-1)) / 10000) % 100);
+ aReturn.Seconds = (short)((((int)(_nVal >= 0 ? _nVal : _nVal*-1)) / 100) % 100);
+ aReturn.HundredthSeconds = (short)(((int)(_nVal >= 0 ? _nVal : _nVal*-1)) % 100);
+ return aReturn;
+ }
+
+ public static Time toTime(double dVal) {
+ int nDays = (int)dVal;
+ int nMS = (int)((dVal - (double)nDays) * fMilliSecondsPerDay + 0.5);
+
+ short nSign;
+ if ( nMS < 0 )
+ {
+ nMS *= -1;
+ nSign = -1;
+ }
+ else
+ nSign = 1;
+
+ Time xRet = new Time();
+ // Zeit normalisieren
+ // we have to sal_Int32 here because otherwise we get an overflow
+ int nHundredthSeconds = nMS/10;
+ int nSeconds = nHundredthSeconds / 100;
+ int nMinutes = nSeconds / 60;
+
+ xRet.HundredthSeconds = (short)(nHundredthSeconds % 100);
+ xRet.Seconds = (short)(nSeconds % 60);
+ xRet.Hours = (short)(nMinutes / 60);
+ xRet.Minutes = (short)(nMinutes % 60);
+
+ // Zeit zusammenbauen
+ int nTime = (int)(xRet.HundredthSeconds + (xRet.Seconds*100) + (xRet.Minutes*10000) + (xRet.Hours*1000000)) * nSign;
+
+ if(nTime < 0)
+ {
+ xRet.HundredthSeconds = 99;
+ xRet.Minutes = 59;
+ xRet.Seconds = 59;
+ xRet.Hours = 23;
+ }
+ return xRet;
+ }
+
+ public static Time toTime(String _sSQLString) {
+ short nHour = 0,
+ nMinute = 0,
+ nSecond = 0,
+ nHundredthSeconds = 0;
+ StringTokenizer tokenizer = new StringTokenizer(_sSQLString, ":");
+ if (tokenizer.hasMoreTokens()) {
+ nHour = (short)safeParseInt(tokenizer.nextToken());
+ }
+ if (tokenizer.hasMoreTokens()) {
+ nMinute = (short)safeParseInt(tokenizer.nextToken());
+ }
+ if (tokenizer.hasMoreTokens()) {
+ String secondAndNano = tokenizer.nextToken();
+ int dot = secondAndNano.indexOf(".");
+ if (dot >= 0) {
+ nSecond = (short)safeParseInt(secondAndNano.substring(0, dot));
+ String nano = secondAndNano.substring(dot + 1);
+ nano = nano.substring(0, 2);
+ nano = nano + "00".substring(0, 2 - nano.length());
+ nHundredthSeconds = (short)safeParseInt(nano);
+ } else {
+ nSecond = (short)safeParseInt(secondAndNano);
+ }
+ }
+ return new Time(nHundredthSeconds,nSecond,nMinute,nHour);
+ }
+
+ public static String toDateString(Date date) {
+ return String.format("%04d-%02d-%02d",
+ Short.toUnsignedInt(date.Year),
+ Short.toUnsignedInt(date.Month),
+ Short.toUnsignedInt(date.Day));
+ }
+
+ public static String toTimeString(Time time) {
+ return String.format("%02d:%02d:%02d",
+ Short.toUnsignedInt(time.Hours),
+ Short.toUnsignedInt(time.Minutes),
+ Short.toUnsignedInt(time.Seconds));
+ }
+
+ public static String toDateTimeString(DateTime dateTime) {
+ return String.format("%04d-%02d-%02d %02d:%02d:%02d.%d",
+ Short.toUnsignedInt(dateTime.Year),
+ Short.toUnsignedInt(dateTime.Month),
+ Short.toUnsignedInt(dateTime.Day),
+ Short.toUnsignedInt(dateTime.Hours),
+ Short.toUnsignedInt(dateTime.Minutes),
+ Short.toUnsignedInt(dateTime.Seconds),
+ Short.toUnsignedInt(dateTime.HundredthSeconds));
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DatabaseMetaDataResultSet.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DatabaseMetaDataResultSet.java
new file mode 100644
index 000000000000..ae722c1bf2f7
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DatabaseMetaDataResultSet.java
@@ -0,0 +1,489 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertyChangeListener;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+import com.sun.star.beans.XVetoableChangeListener;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.io.XInputStream;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lib.uno.helper.ComponentBase;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XArray;
+import com.sun.star.sdbc.XBlob;
+import com.sun.star.sdbc.XClob;
+import com.sun.star.sdbc.XCloseable;
+import com.sun.star.sdbc.XColumnLocate;
+import com.sun.star.sdbc.XRef;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XResultSetMetaData;
+import com.sun.star.sdbc.XResultSetMetaDataSupplier;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbcx.CompareBookmark;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.XRowLocate;
+import com.sun.star.sdbcx.comp.postgresql.PostgresqlResultSetMetaData;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.util.Date;
+import com.sun.star.util.DateTime;
+import com.sun.star.util.Time;
+
+public class DatabaseMetaDataResultSet extends ComponentBase
+ implements XResultSet, XCloseable, XColumnsSupplier, XRowLocate, XPropertySet, XColumnLocate, XRow, XResultSetMetaDataSupplier {
+
+ private XCloseable implCloseable;
+ private XResultSetMetaDataSupplier implResultSetMetaDataSupplier;
+ private XColumnLocate implColumnLocate;
+ private XPropertySet implPropertySet;
+ private XColumnsSupplier implColumnSupplier;
+ private ArrayList<ORowSetValue[]> rows;
+ private AtomicBoolean isDisposed = new AtomicBoolean(false);
+ /// 0-based:
+ private int currentRow = -1;
+ /// 1-based:
+ private int currentColumn;
+
+ public DatabaseMetaDataResultSet(XResultSet impl, ArrayList<ORowSetValue[]> rows) {
+ implCloseable = UnoRuntime.queryInterface(XCloseable.class, impl);
+ implPropertySet = UnoRuntime.queryInterface(XPropertySet.class, impl);
+ implColumnSupplier = UnoRuntime.queryInterface(XColumnsSupplier.class, impl);
+ implColumnLocate = UnoRuntime.queryInterface(XColumnLocate.class, impl);
+ implResultSetMetaDataSupplier = UnoRuntime.queryInterface(XResultSetMetaDataSupplier.class, impl);
+ this.rows = rows;
+ }
+
+ // XComponent:
+ @Override
+ protected void postDisposing() {
+ isDisposed.set(true);
+ try {
+ implCloseable.close();
+ } catch (SQLException sqlException) {
+ }
+ }
+
+ private void checkDisposed() throws DisposedException {
+ if (isDisposed.get()) {
+ throw new DisposedException();
+ }
+ }
+
+ // XCloseable:
+
+ public void close() throws SQLException {
+ dispose();
+ }
+
+ // XResultSet:
+
+ private ORowSetValue getField(int columnIndex) throws SQLException {
+ if (isBeforeFirst() || isAfterLast()) {
+ throw new SQLException("Row out of range");
+ }
+ ORowSetValue[] fields = rows.get(currentRow);
+ if (columnIndex < 1 || fields.length < columnIndex) {
+ throw new SQLException("Column out of range");
+ }
+ currentColumn = columnIndex;
+ return fields[columnIndex - 1];
+ }
+
+ public synchronized boolean absolute(int position) throws SQLException {
+ checkDisposed();
+ if (position >= 0) {
+ currentRow = position;
+ } else {
+ currentRow = rows.size() + position;
+ }
+ if (currentRow <= -1) {
+ currentRow = -1;
+ return false;
+ }
+ if (currentRow >= rows.size()) {
+ currentRow = rows.size();
+ return false;
+ }
+ return true;
+ }
+
+ public synchronized void afterLast() throws SQLException {
+ checkDisposed();
+ currentRow = rows.size();
+ }
+
+ public synchronized void beforeFirst() throws SQLException {
+ checkDisposed();
+ currentRow = -1;
+ }
+
+ public synchronized boolean first() throws SQLException {
+ checkDisposed();
+ currentRow = 0;
+ return true;
+ }
+
+ public synchronized int getRow() throws SQLException {
+ checkDisposed();
+ return currentRow + 1;
+ }
+
+ public Object getStatement() throws SQLException {
+ checkDisposed();
+ return null;
+ }
+
+ public synchronized boolean isAfterLast() throws SQLException {
+ checkDisposed();
+ return currentRow == rows.size();
+ }
+
+ public synchronized boolean isBeforeFirst() throws SQLException {
+ checkDisposed();
+ return currentRow == -1;
+ }
+
+ public synchronized boolean isFirst() throws SQLException {
+ checkDisposed();
+ return currentRow == 0;
+ }
+
+ public synchronized boolean isLast() throws SQLException {
+ checkDisposed();
+ return currentRow == (rows.size() - 1);
+ }
+
+ public synchronized boolean last() throws SQLException {
+ checkDisposed();
+ currentRow = rows.size() - 1;
+ return true;
+ }
+
+ public synchronized boolean next() throws SQLException {
+ checkDisposed();
+ if (currentRow < rows.size()) {
+ ++currentRow;
+ }
+ return currentRow < rows.size();
+ }
+
+ public synchronized boolean previous() throws SQLException {
+ checkDisposed();
+ if (currentRow > -1) {
+ --currentRow;
+ }
+ return currentRow > -1;
+ }
+
+ public void refreshRow() throws SQLException {
+ checkDisposed();
+ }
+
+ public synchronized boolean relative(int offset) throws SQLException {
+ checkDisposed();
+ currentRow += offset;
+ if (currentRow <= -1) {
+ currentRow = -1;
+ return false;
+ }
+ if (currentRow >= rows.size()) {
+ currentRow = rows.size();
+ return false;
+ }
+ return true;
+ }
+
+ public boolean rowDeleted() throws SQLException {
+ checkDisposed();
+ return false;
+ }
+
+ public boolean rowInserted() throws SQLException {
+ checkDisposed();
+ return false;
+ }
+
+ public boolean rowUpdated() throws SQLException {
+ checkDisposed();
+ return false;
+ }
+
+ // XResultSetMetaDataSupplier:
+
+ public XResultSetMetaData getMetaData() throws SQLException {
+ checkDisposed();
+ return new PostgresqlResultSetMetaData(implResultSetMetaDataSupplier.getMetaData());
+ }
+
+ // XRow:
+
+ public XArray getArray(int columnIndex) throws SQLException {
+ checkDisposed();
+ return null;
+ }
+
+ public XInputStream getBinaryStream(int columnIndex) throws SQLException {
+ checkDisposed();
+ return null;
+ }
+
+ public XBlob getBlob(int columnIndex) throws SQLException {
+ checkDisposed();
+ return null;
+ }
+
+ public synchronized boolean getBoolean(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getBoolean();
+ }
+
+ public synchronized byte getByte(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getInt8();
+ }
+
+ public synchronized byte[] getBytes(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getSequence();
+ }
+
+ public XInputStream getCharacterStream(int columnIndex) throws SQLException {
+ checkDisposed();
+ return null;
+ }
+
+ public XClob getClob(int columnIndex) throws SQLException {
+ checkDisposed();
+ return null;
+ }
+
+ public synchronized Date getDate(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getDate();
+ }
+
+ public synchronized double getDouble(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getDouble();
+ }
+
+ public synchronized float getFloat(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getFloat();
+ }
+
+ public synchronized int getInt(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getInt32();
+ }
+
+ public synchronized long getLong(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getLong();
+ }
+
+ public synchronized Object getObject(int columnIndex, XNameAccess arg1) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.makeAny();
+ }
+
+ public XRef getRef(int columnIndex) throws SQLException {
+ checkDisposed();
+ return null;
+ }
+
+ public synchronized short getShort(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getInt16();
+ }
+
+ public synchronized String getString(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getString();
+ }
+
+ public synchronized Time getTime(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getTime();
+ }
+
+ public synchronized DateTime getTimestamp(int columnIndex) throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(columnIndex);
+ return field.getDateTime();
+ }
+
+ public synchronized boolean wasNull() throws SQLException {
+ checkDisposed();
+ ORowSetValue field = getField(currentColumn);
+ return field.isNull();
+ }
+
+ // XColumnLocate:
+
+ public int findColumn(String arg0) throws SQLException {
+ checkDisposed();
+ return implColumnLocate.findColumn(arg0);
+ }
+
+ // XPropertySet:
+
+ public void addPropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.addPropertyChangeListener(arg0, arg1);
+ }
+
+ public void addVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.addVetoableChangeListener(arg0, arg1);
+ }
+
+ public XPropertySetInfo getPropertySetInfo() {
+ checkDisposed();
+ return implPropertySet.getPropertySetInfo();
+ }
+
+ public Object getPropertyValue(String arg0) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ return implPropertySet.getPropertyValue(arg0);
+ }
+
+ public void removePropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.removePropertyChangeListener(arg0, arg1);
+ }
+
+ public void removeVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.removeVetoableChangeListener(arg0, arg1);
+ }
+
+ public void setPropertyValue(String arg0, Object arg1)
+ throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
+ checkDisposed();
+ implPropertySet.setPropertyValue(arg0, arg1);
+ }
+
+ // XRowLocate:
+
+ public int compareBookmarks(Object arg0, Object arg1) throws SQLException {
+ checkDisposed();
+
+ int bookmark1, bookmark2;
+ try {
+ bookmark1 = AnyConverter.toInt(arg0);
+ bookmark2 = AnyConverter.toInt(arg1);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ return CompareBookmark.NOT_COMPARABLE;
+ }
+
+ if (bookmark1 < bookmark2) {
+ return CompareBookmark.LESS;
+ } else if (bookmark1 > bookmark2) {
+ return CompareBookmark.GREATER;
+ } else {
+ return CompareBookmark.EQUAL;
+ }
+ }
+
+ public Object getBookmark() throws SQLException {
+ checkDisposed();
+ return currentRow;
+ }
+
+ public boolean hasOrderedBookmarks() throws SQLException {
+ checkDisposed();
+ return true;
+ }
+
+ public int hashBookmark(Object arg0) throws SQLException {
+ checkDisposed();
+ int bookmark;
+ try {
+ bookmark = AnyConverter.toInt(arg0);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw new SQLException("Bad bookmark", this, StandardSQLState.SQL_INVALID_BOOKMARK_VALUE.text(), 0, null);
+ }
+ return bookmark;
+ }
+
+ public boolean moveRelativeToBookmark(Object arg0, int arg1) throws SQLException {
+ checkDisposed();
+ int bookmark;
+ boolean moved = false;
+ try {
+ bookmark = AnyConverter.toInt(arg0);
+ moved = absolute(bookmark);
+ if (moved) {
+ moved = relative(arg1);
+ }
+ } catch (IllegalArgumentException illegalArgumentException) {
+ }
+ if (!moved) {
+ afterLast();
+ }
+ return moved;
+ }
+
+ public boolean moveToBookmark(Object arg0) throws SQLException {
+ checkDisposed();
+ int bookmark;
+ boolean moved = false;
+ try {
+ bookmark = AnyConverter.toInt(arg0);
+ moved = absolute(bookmark);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ }
+ if (!moved) {
+ afterLast();
+ }
+ return moved;
+ }
+
+ // XColumnSupplier:
+
+ public XNameAccess getColumns() {
+ checkDisposed();
+ return implColumnSupplier.getColumns();
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DbTools.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DbTools.java
new file mode 100644
index 000000000000..5837c3e468ef
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DbTools.java
@@ -0,0 +1,679 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+import com.sun.star.container.ElementExistException;
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.IndexOutOfBoundsException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.sdbc.ColumnValue;
+import com.sun.star.sdbc.DataType;
+import com.sun.star.sdbc.KeyRule;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XConnection;
+import com.sun.star.sdbc.XDatabaseMetaData;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XResultSetMetaData;
+import com.sun.star.sdbc.XResultSetMetaDataSupplier;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbc.XStatement;
+import com.sun.star.sdbcx.KeyType;
+import com.sun.star.sdbcx.XAppend;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.sdbcx.XKeysSupplier;
+import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.ISQLStatementHelper;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.OColumnContainer.ExtraColumnInfo;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.Resources;
+import com.sun.star.sdbcx.comp.postgresql.sdbcx.SharedResources;
+import com.sun.star.uno.Any;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+
+public class DbTools {
+ private static class NameComponentSupport {
+ boolean useCatalogs;
+ boolean useSchemas;
+
+ NameComponentSupport() {
+ useCatalogs = true;
+ useSchemas = true;
+ }
+
+ NameComponentSupport(boolean useCatalogs, boolean useSchemas) {
+ this.useCatalogs = useCatalogs;
+ this.useSchemas = useSchemas;
+ }
+ }
+
+ public static class NameComponents {
+ private String catalog = "";
+ private String schema = "";
+ private String table = "";
+
+ public NameComponents(String catalog, String schema, String table) {
+ this.catalog = catalog;
+ this.schema = schema;
+ this.table = table;
+ }
+
+ public NameComponents() {
+ }
+
+ public String getCatalog() {
+ return catalog;
+ }
+
+ public void setCatalog(String catalog) {
+ this.catalog = catalog;
+ }
+
+ public String getSchema() {
+ return schema;
+ }
+
+ public void setSchema(String schema) {
+ this.schema = schema;
+ }
+
+ public String getTable() {
+ return table;
+ }
+
+ public void setTable(String table) {
+ this.table = table;
+ }
+ }
+
+ private static NameComponentSupport getNameComponentSupport(XDatabaseMetaData metadata, ComposeRule composeRule) throws SQLException {
+ switch (composeRule) {
+ case InTableDefinitions:
+ return new NameComponentSupport(
+ metadata.supportsCatalogsInTableDefinitions(), metadata.supportsSchemasInTableDefinitions());
+ case InIndexDefinitions:
+ return new NameComponentSupport(
+ metadata.supportsCatalogsInIndexDefinitions(), metadata.supportsSchemasInIndexDefinitions());
+ case InDataManipulation:
+ return new NameComponentSupport(
+ metadata.supportsCatalogsInDataManipulation(), metadata.supportsSchemasInDataManipulation());
+ case InProcedureCalls:
+ return new NameComponentSupport(
+ metadata.supportsCatalogsInProcedureCalls(), metadata.supportsSchemasInProcedureCalls());
+ case InPrivilegeDefinitions:
+ return new NameComponentSupport(
+ metadata.supportsCatalogsInPrivilegeDefinitions(), metadata.supportsSchemasInPrivilegeDefinitions());
+ case Complete:
+ return new NameComponentSupport(
+ true, true);
+ default:
+ throw new UnsupportedOperationException("Invalid/unknown enum value");
+ }
+ }
+
+ public static String composeTableName(
+ XDatabaseMetaData metadata, String catalog, String schema, String table, boolean quote, ComposeRule composeRule) throws SQLException {
+ if (metadata == null) {
+ return "";
+ }
+ String quoteString = metadata.getIdentifierQuoteString();
+ NameComponentSupport nameComponentSupport = getNameComponentSupport(metadata, composeRule);
+
+ StringBuilder composedName = new StringBuilder();
+
+ String catalogSeparator = "";
+ boolean catalogAtStart = true;
+ if (!catalog.isEmpty() && nameComponentSupport.useCatalogs) {
+ catalogSeparator = metadata.getCatalogSeparator();
+ catalogAtStart = metadata.isCatalogAtStart();
+ if (catalogAtStart && !catalogSeparator.isEmpty()) {
+ composedName.append(quote ? quoteName(quoteString, catalog) : catalog);
+ composedName.append(catalogSeparator);
+ }
+ }
+ if (!schema.isEmpty() && nameComponentSupport.useSchemas) {
+ composedName.append(quote ? quoteName(quoteString, schema) : schema);
+ composedName.append('.');
+ }
+ composedName.append(quote ? quoteName(quoteString, table) : table);
+ if (!catalog.isEmpty() && !catalogAtStart && !catalogSeparator.isEmpty() && nameComponentSupport.useCatalogs) {
+ composedName.append(catalogSeparator);
+ composedName.append(quote ? quoteName(quoteString, catalog) : catalog);
+ }
+ return composedName.toString();
+ }
+
+ public static String composeTableName(
+ XDatabaseMetaData metadata, XPropertySet table, ComposeRule composeRule,
+ boolean suppressCatalog, boolean suppressSchema, boolean shouldQuote) throws SQLException {
+ MutableObject<String> catalog = new MutableObject<>("");
+ MutableObject<String> schema = new MutableObject<>("");
+ MutableObject<String> name = new MutableObject<>("");
+ getTableNameComponents(table, catalog, schema, name);
+ return doComposeTableName(metadata,
+ suppressCatalog ? "" : catalog.getValue(),
+ suppressSchema ? "" : schema.getValue(),
+ name.getValue(),
+ shouldQuote, composeRule);
+ }
+
+ public static boolean isDataSourcePropertyEnabled(Object object, String property, boolean defaultValue) throws SQLException {
+ try {
+ boolean enabled = defaultValue;
+ XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, object);
+ if (properties != null) {
+ PropertyValue[] info = (PropertyValue[]) AnyConverter.toArray(properties.getPropertyValue("Info"));
+ for (PropertyValue propertyValue : info) {
+ if (propertyValue.Name.equals(property)) {
+ enabled = AnyConverter.toBoolean(propertyValue.Value);
+ break;
+ }
+ }
+ }
+ return enabled;
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw new SQLException("Error", object, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, illegalArgumentException);
+ } catch (WrappedTargetException wrappedTargetException) {
+ throw new SQLException("Error", object, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, wrappedTargetException);
+ } catch (UnknownPropertyException unknownPropertyException) {
+ throw new SQLException("Error", object, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, unknownPropertyException);
+ }
+ }
+
+ public static String doComposeTableName(XDatabaseMetaData metadata, String catalog, String schema, String table,
+ boolean shouldQuote, ComposeRule composeRule) throws SQLException {
+ System.out.println(String.format("doComposeTableName(%s, %s, %s)\n", catalog, schema, table));
+ Osl.ensure(!table.isEmpty(), "At least the table name should be non-empty");
+ String quoteString = metadata.getIdentifierQuoteString();
+ NameComponentSupport nameComponentSupport = getNameComponentSupport(metadata, composeRule);
+
+ StringBuilder composedName = new StringBuilder();
+ String catalogSeparator = "";
+ boolean catalogAtStart = true;
+ if (!catalog.isEmpty() && nameComponentSupport.useCatalogs) {
+ catalogSeparator = metadata.getCatalogSeparator();
+ catalogAtStart = metadata.isCatalogAtStart();
+
+ if (catalogAtStart && !catalogSeparator.isEmpty()) {
+ composedName.append(shouldQuote ? quoteName(quoteString, catalog) : catalog);
+ composedName.append(catalogSeparator);
+ }
+ }
+
+ if (!schema.isEmpty() && nameComponentSupport.useSchemas) {
+ composedName.append(shouldQuote ? quoteName(quoteString, schema) : schema);
+ composedName.append(".");
+ }
+
+ composedName.append(shouldQuote ? quoteName(quoteString, table) : table);
+
+ if (!catalog.isEmpty() && !catalogAtStart && !catalogSeparator.isEmpty() && nameComponentSupport.useCatalogs) {
+ composedName.append(catalogSeparator);
+ composedName.append(shouldQuote ? quoteName(quoteString, catalog) : catalog);
+ }
+ return composedName.toString();
+ }
+
+ public static String composeTableNameForSelect(XConnection connection, String catalog,
+ String schema, String table) throws SQLException {
+ boolean useCatalogInSelect = isDataSourcePropertyEnabled(connection, "UseCatalogInSelect", true);
+ boolean useSchemaInSelect = isDataSourcePropertyEnabled(connection, "UseSchemaInSelect", true);
+ return doComposeTableName(connection.getMetaData(), useCatalogInSelect ? catalog : "",
+ useSchemaInSelect ? schema : "", table, true, ComposeRule.InDataManipulation);
+ }
+
+ public static String composeTableNameForSelect(XConnection connection, XPropertySet table) throws SQLException {
+ MutableObject<String> catalog = new MutableObject<>();
+ MutableObject<String> schema = new MutableObject<>();
+ MutableObject<String> tableName = new MutableObject<>();
+ getTableNameComponents(table, catalog, schema, tableName);
+ return composeTableNameForSelect(connection, catalog.getValue(), schema.getValue(), tableName.getValue());
+ }
+
+ private static void getTableNameComponents(XPropertySet table, MutableObject<String> catalog,
+ MutableObject<String> schema, MutableObject<String> tableName) {
+ try {
+ XPropertySetInfo propertySetInfo = table.getPropertySetInfo();
+ if (propertySetInfo != null && propertySetInfo.hasPropertyByName(PropertyIds.NAME.name)) {
+ if (propertySetInfo.hasPropertyByName(PropertyIds.CATALOGNAME.name)
+ && propertySetInfo.hasPropertyByName(PropertyIds.SCHEMANAME.name)) {
+ catalog.setValue(AnyConverter.toString(table.getPropertyValue(PropertyIds.CATALOGNAME.name)));
+ schema.setValue(AnyConverter.toString(table.getPropertyValue(PropertyIds.SCHEMANAME.name)));
+ }
+ tableName.setValue(AnyConverter.toString(table.getPropertyValue(PropertyIds.NAME.name)));
+ } else {
+ Osl.ensure(false, "not a table");
+ }
+ } catch (IllegalArgumentException illegalArgumentException) {
+ } catch (WrappedTargetException wrappedTargetException) {
+ } catch (UnknownPropertyException unknownPropertyException) {
+ }
+ }
+
+ public static String quoteName(String quote, String name) {
+ if (!quote.isEmpty() && quote.codePointAt(0) != ' ') {
+ return quote + name + quote;
+ }
+ return name;
+ }
+
+ public static String quoteTableName(XDatabaseMetaData metadata, String name, ComposeRule composeRule) throws SQLException {
+ NameComponents nameComponents = qualifiedNameComponents(metadata, name, composeRule);
+ return doComposeTableName(metadata, nameComponents.getCatalog(), nameComponents.getSchema(), nameComponents.getTable(), true, composeRule);
+ }
+
+ public static NameComponents qualifiedNameComponents(XDatabaseMetaData _rxConnMetaData, String _rQualifiedName,
+ ComposeRule _eComposeRule) throws SQLException {
+ Osl.ensure(_rxConnMetaData, "QualifiedNameComponents : invalid meta data!");
+
+ NameComponentSupport aNameComps = getNameComponentSupport( _rxConnMetaData, _eComposeRule );
+
+ String sSeparator = _rxConnMetaData.getCatalogSeparator();
+ NameComponents ret = new NameComponents();
+
+ String sName = _rQualifiedName;
+ // do we have catalogs ?
+ if ( aNameComps.useCatalogs ) {
+ if (_rxConnMetaData.isCatalogAtStart()) {
+ // search for the catalog name at the beginning
+ int nIndex = sName.indexOf(sSeparator);
+ if (-1 != nIndex) {
+ ret.setCatalog(sName.substring(0, nIndex));
+ sName = sName.substring(nIndex + 1);
+ }
+ } else {
+ // Katalogname am Ende
+ int nIndex = sName.lastIndexOf(sSeparator);
+ if (-1 != nIndex) {
+ ret.setCatalog(sName.substring(nIndex + 1));
+ sName = sName.substring(0, nIndex);
+ }
+ }
+ }
+
+ if ( aNameComps.useSchemas ) {
+ int nIndex = sName.indexOf('.');
+ Osl.ensure(-1 != nIndex, "QualifiedNameComponents : no schema separator!");
+ if ( nIndex != -1 ) {
+ ret.setSchema(sName.substring(0, nIndex));
+ }
+ sName = sName.substring(nIndex + 1);
+ }
+
+ ret.setTable(sName);
+ return ret;
+ }
+
+ public static String createSqlCreateTableStatement(XPropertySet descriptor, XConnection connection,
+ ISQLStatementHelper helper, String createPattern) throws
+ SQLException, WrappedTargetException, UnknownPropertyException, IllegalArgumentException, IndexOutOfBoundsException {
+
+ String sql = createStandardCreateStatement(descriptor, connection, helper, createPattern);
+ final String keyStatement = createStandardKeyStatement(descriptor, connection);
+ if (!keyStatement.isEmpty()) {
+ sql += keyStatement;
+ } else {
+ sql += ')';
+ }
+ return sql;
+ }
+
+ public static String createStandardCreateStatement(XPropertySet descriptor, XConnection connection,
+ ISQLStatementHelper helper, String createPattern) throws
+ SQLException, WrappedTargetException, UnknownPropertyException, IllegalArgumentException, IndexOutOfBoundsException {
+
+ XDatabaseMetaData metadata = connection.getMetaData();
+ String catalog = AnyConverter.toString(descriptor.getPropertyValue("CatalogName"));
+ String schema = AnyConverter.toString(descriptor.getPropertyValue("SchemaName"));
+ String table = AnyConverter.toString(descriptor.getPropertyValue("Name"));
+ String composedName = composeTableName(metadata, catalog, schema, table, true, ComposeRule.InTableDefinitions);
+ if (composedName.isEmpty()) {
+ throw new SQLException(SharedResources.getInstance().getResourceString(Resources.STR_ERRORMSG_SEQUENCE), connection,
+ StandardSQLState.SQL_FUNCTION_SEQUENCE_ERROR.text(), 0, null);
+ }
+
+ XIndexAccess columns = null;
+ XColumnsSupplier columnsSupplier = UnoRuntime.queryInterface(XColumnsSupplier.class, descriptor);
+ if (columnsSupplier != null) {
+ columns = UnoRuntime.queryInterface(XIndexAccess.class, columnsSupplier.getColumns());
+ }
+ if (columns == null || columns.getCount() <= 0) {
+ throw new SQLException(SharedResources.getInstance().getResourceString(Resources.STR_ERRORMSG_SEQUENCE), connection,
+ StandardSQLState.SQL_FUNCTION_SEQUENCE_ERROR.text(), 0, null);
+ }
+
+ int columnCount = columns.getCount();
+ StringBuilder columnText = new StringBuilder();
+ String separator = "";
+ for (int i = 0; i < columnCount; i++) {
+ XPropertySet columnProperties;
+ columnProperties = AnyConverter.toObject(XPropertySet.class, columns.getByIndex(i));
+ if (columnProperties != null) {
+ columnText.append(separator);
+ separator = ",";
+ columnText.append(createStandardColumnPart(columnProperties, connection, helper, createPattern));
+ }
+ }
+
+ return String.format("CREATE TABLE %s (%s", composedName, columnText.toString());
+ }
+
+ public static String createStandardColumnPart(XPropertySet columnProperties, XConnection connection,
+ ISQLStatementHelper helper, String createPattern) throws
+ SQLException, WrappedTargetException, UnknownPropertyException, IllegalArgumentException, IndexOutOfBoundsException {
+
+ XDatabaseMetaData metadata = connection.getMetaData();
+
+ final String quoteString = metadata.getIdentifierQuoteString();
+ final StringBuilder sql = new StringBuilder();
+ sql.append(quoteName(quoteString, AnyConverter.toString(columnProperties.getPropertyValue("Name"))));
+ sql.append(' ');
+
+ String typename = AnyConverter.toString(columnProperties.getPropertyValue("TypeName"));
+ int datatype = AnyConverter.toInt(columnProperties.getPropertyValue("Type"));
+ int precision = AnyConverter.toInt(columnProperties.getPropertyValue("Precision"));
+ int scale = AnyConverter.toInt(columnProperties.getPropertyValue("Scale"));
+ boolean isAutoIncrement = AnyConverter.toBoolean(columnProperties.getPropertyValue("IsAutoIncrement"));
+
+ // check if the user enter a specific string to create autoincrement values
+ String autoIncrementValue = "";
+ XPropertySetInfo columnPropertiesInfo = columnProperties.getPropertySetInfo();
+ if (columnPropertiesInfo != null && columnPropertiesInfo.hasPropertyByName("AutoIncrementCreation")) {
+ autoIncrementValue = AnyConverter.toString(columnProperties.getPropertyValue("AutoIncrementCreation"));
+ }
+
+ // look if we have to use precisions
+ boolean useLiteral = false;
+ String prefix = "";
+ String postfix ="";
+ String createParams = "";
+ XResultSet results = null;
+ try {
+ results = metadata.getTypeInfo();
+ if (results != null) {
+ XRow row = UnoRuntime.queryInterface(XRow.class, results);
+ while (results.next()) {
+ String typeName2Cmp = row.getString(1);
+ int nType = row.getShort(2);
+ prefix = row.getString(4);
+ postfix = row.getString(5);
+ createParams = row.getString(6);
+ // first identical type will be used if typename is empty
+ if (typename.isEmpty() && nType == datatype) {
+ typename = typeName2Cmp;
+ }
+ if (typename.equals(typeName2Cmp) && nType == datatype && !row.wasNull() && !createParams.isEmpty()) {
+ useLiteral = true;
+ break;
+ }
+ }
+ }
+ } finally {
+ CompHelper.disposeComponent(results);
+ }
+
+ int index = 0;
+ if (!autoIncrementValue.isEmpty() && (index = typename.indexOf(autoIncrementValue)) != -1) {
+ typename = typename.substring(0, index);
+ }
+
+ if ((precision > 0 || scale > 0) && useLiteral) {
+ int parenPos = typename.indexOf('(');
+ if (parenPos == -1) {
+ sql.append(typename);
+ sql.append('(');
+ } else {
+ sql.append(typename.substring(0, ++parenPos));
+ }
+
+ if (precision > 0 && datatype != DataType.TIMESTAMP) {
+ sql.append(precision);
+ if (scale > 0 || (!createPattern.isEmpty() && createParams.indexOf(createPattern) != -1)) {
+ sql.append(',');
+ }
+ }
+ if (scale > 0 || (!createPattern.isEmpty() && createParams.indexOf(createPattern) != -1) || datatype == DataType.TIMESTAMP) {
+ sql.append(scale);
+ }
+ if (parenPos == -1) {
+ sql.append(')');
+ } else {
+ parenPos = typename.indexOf(')', parenPos);
+ sql.append(typename.substring(parenPos));
+ }
+ } else {
+ sql.append(typename); // simply add the type name
+ }
+
+ String defaultValue = AnyConverter.toString(columnProperties.getPropertyValue("DefaultValue"));
+ if (defaultValue != null && !defaultValue.isEmpty()) {
+ sql.append(" DEFAULT ");
+ sql.append(prefix);
+ sql.append(defaultValue);
+ sql.append(postfix);
+ }
+
+ if (AnyConverter.toInt(columnProperties.getPropertyValue("IsNullable")) == ColumnValue.NO_NULLS) {
+ sql.append(" NOT NULL");
+ }
+
+ if (isAutoIncrement && !autoIncrementValue.isEmpty()) {
+ sql.append(' ');
+ sql.append(autoIncrementValue);
+ }
+
+ if (helper != null) {
+ helper.addComment(columnProperties, sql);
+ }
+
+ return sql.toString();
+ }
+
+ public static String createStandardKeyStatement(XPropertySet descriptor, XConnection connection) throws
+ SQLException, WrappedTargetException, UnknownPropertyException, IllegalArgumentException, IndexOutOfBoundsException {
+ XDatabaseMetaData metadata = connection.getMetaData();
+ StringBuilder sql = new StringBuilder();
+
+ XKeysSupplier keysSupplier = UnoRuntime.queryInterface(XKeysSupplier.class, descriptor);
+ XIndexAccess keys = keysSupplier.getKeys();
+ if (keys != null) {
+ boolean hasPrimaryKey = false;
+ for (int i = 0; i < keys.getCount(); i++) {
+ XPropertySet columnProperties = AnyConverter.toObject(XPropertySet.class, keys.getByIndex(i));
+ if (columnProperties != null) {
+ int keyType = AnyConverter.toInt(columnProperties.getPropertyValue("Type"));
+ XColumnsSupplier columnsSupplier = UnoRuntime.queryInterface(XColumnsSupplier.class, columnProperties);
+ XIndexAccess columns = UnoRuntime.queryInterface(XIndexAccess.class, columnsSupplier.getColumns());
+ if (columns == null || columns.getCount() == 0) {
+ throw new SQLException(SharedResources.getInstance().getResourceString(Resources.STR_ERRORMSG_SEQUENCE), connection,
+ StandardSQLState.SQL_FUNCTION_SEQUENCE_ERROR.text(), 0, null);
+ }
+ if (keyType == KeyType.PRIMARY) {
+ if (hasPrimaryKey) {
+ throw new SQLException(SharedResources.getInstance().getResourceString(Resources.STR_ERRORMSG_SEQUENCE), connection,
+ StandardSQLState.SQL_FUNCTION_SEQUENCE_ERROR.text(), 0, null);
+ }
+ hasPrimaryKey = true;
+ sql.append(" PRIMARY KEY ");
+ sql.append(generateColumnNames(columns, metadata));
+ } else if (keyType == KeyType.UNIQUE) {
+ sql.append(" UNIQUE ");
+ sql.append(generateColumnNames(columns, metadata));
+ } else if (keyType == KeyType.FOREIGN) {
+ int deleteRule = AnyConverter.toInt(columnProperties.getPropertyValue("DeleteRule"));
+ sql.append(" FOREIGN KEY ");
+ sql.append(generateColumnNames(columns, metadata));
+
+ String referencedTable = AnyConverter.toString(columnProperties.getPropertyValue("ReferencedTable"));
+ NameComponents nameComponents = qualifiedNameComponents(metadata, referencedTable, ComposeRule.InDataManipulation);
+ String composedName = composeTableName(metadata, nameComponents.getCatalog(), nameComponents.getSchema(), nameComponents.getTable(),
+ true, ComposeRule.InTableDefinitions);
+ if (composedName.isEmpty()) {
+ throw new SQLException(SharedResources.getInstance().getResourceString(Resources.STR_ERRORMSG_SEQUENCE), connection,
+ StandardSQLState.SQL_FUNCTION_SEQUENCE_ERROR.text(), 0, null);
+ }
+
+ switch (deleteRule) {
+ case KeyRule.CASCADE:
+ sql.append(" ON DELETE CASCADE ");
+ break;
+ case KeyRule.RESTRICT:
+ sql.append(" ON DELETE RESTRICT ");
+ break;
+ case KeyRule.SET_NULL:
+ sql.append(" ON DELETE SET NULL ");
+ break;
+ case KeyRule.SET_DEFAULT:
+ sql.append(" ON DELETE SET DEFAULT ");
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (sql.length() > 0) {
+ sql.append(')');
+ }
+ return sql.toString();
+ }
+
+ private static String generateColumnNames(XIndexAccess columns, XDatabaseMetaData metadata) throws
+ SQLException, WrappedTargetException, UnknownPropertyException, IllegalArgumentException, IndexOutOfBoundsException {
+ String quote = metadata.getIdentifierQuoteString();
+ StringBuilder sql = new StringBuilder(" (");
+ int columnCount = columns.getCount();
+ String separator = "";
+ for (int i = 0; i < columnCount; i++) {
+ XPropertySet columnProperties = AnyConverter.toObject(XPropertySet.class, columns.getByIndex(i));
+ if (columnProperties != null) {
+ sql.append(separator);
+ separator = ",";
+ String columnName = AnyConverter.toString(columnProperties.getPropertyValue("Name"));
+ sql.append(quoteName(quote, columnName));
+ }
+ }
+ if (columnCount > 0) {
+ sql.append(')');
+ }
+ return sql.toString();
+ }
+
+ public static Map<String,ExtraColumnInfo> collectColumnInformation(XConnection connection, String composedName, String columnName) throws SQLException {
+ String sql = String.format("SELECT %s FROM %s WHERE 0 = 1", columnName, composedName);
+ XStatement statement = null;
+ try {
+ statement = connection.createStatement();
+ XPropertySet statementProperties = UnoRuntime.queryInterface(XPropertySet.class, statement);
+ statementProperties.setPropertyValue(PropertyIds.ESCAPEPROCESSING.name, false);
+ XResultSet results = statement.executeQuery(sql);
+ XResultSetMetaDataSupplier metadataSupplier = UnoRuntime.queryInterface(XResultSetMetaDataSupplier.class, results);
+ XResultSetMetaData metadata = metadataSupplier.getMetaData();
+
+ Map<String,ExtraColumnInfo> columns = new TreeMap<>();
+ int count = metadata.getColumnCount();
+ Osl.ensure(count > 0, "resultset has empty metadata");
+ for (int i = 1; i <= count; i++) {
+ String newColumnName = metadata.getColumnName(i);
+ ExtraColumnInfo columnInfo = new ExtraColumnInfo();
+ columnInfo.isAutoIncrement = metadata.isAutoIncrement(i);
+ columnInfo.isCurrency = metadata.isCurrency(i);
+ columnInfo.dataType = metadata.getColumnType(i);
+ columns.put(newColumnName, columnInfo);
+ }
+ return columns;
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw new SQLException();
+ } catch (WrappedTargetException wrappedTargetException) {
+ throw new SQLException();
+ } catch (UnknownPropertyException unknownPropertyException) {
+ throw new SQLException();
+ } catch (PropertyVetoException propertyVetoException) {
+ throw new SQLException();
+ } finally {
+ CompHelper.disposeComponent(statement);
+ }
+ }
+
+ public static XNameAccess getPrimaryKeyColumns(XPropertySet table) throws SQLException {
+ try {
+ XNameAccess keyColumns = null;
+ XKeysSupplier keysSupplier = UnoRuntime.queryInterface(XKeysSupplier.class, table);
+ if (keysSupplier != null) {
+ XIndexAccess keys = keysSupplier.getKeys();
+ if (keys != null) {
+ int count = keys.getCount();
+ for (int i = 0; i < count; i++) {
+ XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, keys.getByIndex(i));
+ if (propertySet != null) {
+ int keyType = 0;
+ keyType = AnyConverter.toInt(propertySet.getPropertyValue(PropertyIds.TYPE.name));
+ if (keyType == KeyType.PRIMARY) {
+ XColumnsSupplier columnsSupplier = UnoRuntime.queryInterface(XColumnsSupplier.class, propertySet);
+ keyColumns = columnsSupplier.getColumns();
+ break;
+ }
+ }
+ }
+ }
+ }
+ return keyColumns;
+ } catch (IndexOutOfBoundsException indexOutOfBoundsException) {
+ throw new SQLException();
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw new SQLException();
+ } catch (WrappedTargetException wrappedTargetException) {
+ throw new SQLException();
+ } catch (UnknownPropertyException unknownPropertyException) {
+ throw new SQLException();
+ }
+ }
+
+ public static void cloneDescriptorColumns(XPropertySet source, XPropertySet destination) throws SQLException {
+ XColumnsSupplier sourceColumnsSupplier = UnoRuntime.queryInterface(XColumnsSupplier.class, source);
+ XIndexAccess sourceColumns = UnoRuntime.queryInterface(XIndexAccess.class, sourceColumnsSupplier.getColumns());
+
+ XColumnsSupplier destinationColumnsSupplier = UnoRuntime.queryInterface(XColumnsSupplier.class, destination);
+ XAppend destinationAppend = UnoRuntime.queryInterface(XAppend.class, destinationColumnsSupplier.getColumns());
+
+ int count = sourceColumns.getCount();
+ for (int i = 0; i < count; i++) {
+ try {
+ XPropertySet columnProperties = AnyConverter.toObject(XPropertySet.class, sourceColumns.getByIndex(i));
+ destinationAppend.appendByDescriptor(columnProperties);
+ } catch (WrappedTargetException | IndexOutOfBoundsException | IllegalArgumentException | ElementExistException exception) {
+ throw new SQLException("Error", Any.VOID, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, exception);
+ }
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameAccessAdapter.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameAccessAdapter.java
new file mode 100644
index 000000000000..991679ba53c5
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameAccessAdapter.java
@@ -0,0 +1,91 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+import java.util.Map;
+
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.Type;
+
+public class MapToXNameAccessAdapter extends WeakBase implements XNameAccess {
+ protected final Map<String,Object> map;
+ protected final Object lock;
+ private final Type elementType;
+
+ public MapToXNameAccessAdapter(Map<String,Object> map, Object lock, Type elementType) {
+ this.map = map;
+ this.lock = lock;
+ this.elementType = elementType;
+ }
+
+ // XNameAccess:
+
+ @Override
+ public Object getByName(String key)
+ throws NoSuchElementException, WrappedTargetException {
+ Object object;
+ synchronized (lock) {
+ object = map.get(key);
+ }
+ if (object == null) {
+ throw new NoSuchElementException();
+ }
+ return object;
+ }
+
+ @Override
+ public String[] getElementNames() {
+ synchronized (lock) {
+ String[] names = new String[map.size()];
+ int next = 0;
+ for (Map.Entry<String,Object> entry : map.entrySet()) {
+ names[next++] = entry.getKey().toString();
+ }
+ return names;
+ }
+ }
+
+ @Override
+ public boolean hasByName(String key) {
+ synchronized (lock) {
+ return map.containsKey(key);
+ }
+ }
+
+ // XElementAccess:
+
+ @Override
+ public Type getElementType() {
+ return elementType;
+ }
+
+
+ @Override
+ public boolean hasElements() {
+ synchronized (lock) {
+ return !map.isEmpty();
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameContainerAdapter.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameContainerAdapter.java
new file mode 100644
index 000000000000..ad5d3afed456
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameContainerAdapter.java
@@ -0,0 +1,77 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+import java.util.Map;
+
+import com.sun.star.container.ElementExistException;
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.container.XNameContainer;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.uno.Type;
+
+public class MapToXNameContainerAdapter extends MapToXNameAccessAdapter implements XNameContainer {
+ public MapToXNameContainerAdapter(Map<String,Object> map, Object lock, Type elementType) {
+ super(map, lock, elementType);
+ }
+
+ // XNameContainer:
+
+ @Override
+ public void insertByName(String key, Object value)
+ throws IllegalArgumentException, ElementExistException,
+ WrappedTargetException {
+ synchronized (lock) {
+ if (map.containsKey(key)) {
+ throw new ElementExistException();
+ }
+ map.put(key, value);
+ }
+ }
+
+ @Override
+ public void removeByName(String key)
+ throws NoSuchElementException, WrappedTargetException {
+ synchronized (lock) {
+ if (map.containsKey(key)) {
+ map.remove(key);
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+ }
+
+ // XNameReplace:
+
+ @Override
+ public void replaceByName(String key, Object value)
+ throws IllegalArgumentException, NoSuchElementException,
+ WrappedTargetException {
+ synchronized (lock) {
+ if (!map.containsKey(key)) {
+ throw new NoSuchElementException();
+ }
+ map.put(key, value);
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ORowSetValue.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ORowSetValue.java
new file mode 100644
index 000000000000..f218b39b4cbd
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ORowSetValue.java
@@ -0,0 +1,1154 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+
+import com.sun.star.io.IOException;
+import com.sun.star.io.XInputStream;
+import com.sun.star.sdbc.DataType;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XBlob;
+import com.sun.star.sdbc.XClob;
+import com.sun.star.uno.Any;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.Type;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.util.Date;
+import com.sun.star.util.DateTime;
+import com.sun.star.util.Time;
+
+public class ORowSetValue {
+ private Object value;
+ private int typeKind;
+ private int flags;
+ private static final int FLAG_NULL = 0b1000;
+ private static final int FLAG_BOUND = 0b0100;
+ private static final int FLAG_MODIFIED = 0b0010;
+ private static final int FLAG_SIGNED = 0b0001;
+
+ public ORowSetValue() {
+ flags = FLAG_NULL | FLAG_BOUND | FLAG_SIGNED;
+ typeKind = DataType.VARCHAR;
+ }
+
+ public ORowSetValue(boolean value) {
+ this();
+ setBoolean(value);
+ }
+
+ public ORowSetValue(Date value) {
+ this();
+ setDate(value);
+ }
+
+ public ORowSetValue(DateTime value) {
+ this();
+ setDateTime(value);
+ }
+
+ public ORowSetValue(double value) {
+ this();
+ setDouble(value);
+ }
+
+ public ORowSetValue(float value) {
+ this();
+ setFloat(value);
+ }
+
+ public ORowSetValue(byte value) {
+ this();
+ setInt8(value);
+ }
+
+ public ORowSetValue(short value) {
+ this();
+ setInt16(value);
+ }
+
+ public ORowSetValue(int value) {
+ this();
+ setInt32(value);
+ }
+
+ public ORowSetValue(long value) {
+ this();
+ setLong(value);
+ }
+
+ public ORowSetValue(byte[] value) {
+ this();
+ setSequence(value);
+ }
+
+ public ORowSetValue(String value) {
+ this();
+ setString(value);
+ }
+
+ public ORowSetValue(Time value) {
+ this();
+ setTime(value);
+ }
+
+ public boolean isNull() {
+ return (flags & FLAG_NULL) != 0;
+ }
+
+ public void setNull() {
+ free();
+ flags |= FLAG_NULL;
+ }
+
+ public boolean isBound() {
+ return (flags & FLAG_BOUND) != 0;
+ }
+
+ public void setBound(boolean isBound) {
+ if (isBound) {
+ flags |= FLAG_BOUND;
+ } else {
+ flags &= ~FLAG_BOUND;
+ }
+ }
+
+ public boolean isModified() {
+ return (flags & FLAG_MODIFIED) != 0;
+ }
+
+ public void setModified(boolean isModified) {
+ flags |= FLAG_MODIFIED;
+ }
+
+ public boolean isSigned() {
+ return (flags & FLAG_SIGNED) != 0;
+ }
+
+ public void setSigned() throws IOException, SQLException {
+ setSigned(true);
+ }
+
+ public void setSigned(boolean isSigned) {
+ if (isSigned) {
+ flags |= FLAG_SIGNED;
+ } else {
+ flags &= ~FLAG_SIGNED;
+ }
+ }
+
+ private boolean isStorageCompatible(int _eType1, int _eType2) {
+ boolean bIsCompatible = true;
+
+ if (_eType1 != _eType2) {
+ switch (_eType1) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ bIsCompatible = (DataType.CHAR == _eType2)
+ || (DataType.VARCHAR == _eType2)
+ || (DataType.DECIMAL == _eType2)
+ || (DataType.NUMERIC == _eType2)
+ || (DataType.LONGVARCHAR == _eType2);
+ break;
+
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ bIsCompatible = (DataType.DOUBLE == _eType2)
+ || (DataType.REAL == _eType2);
+ break;
+
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ bIsCompatible = (DataType.BINARY == _eType2)
+ || (DataType.VARBINARY == _eType2)
+ || (DataType.LONGVARBINARY == _eType2);
+ break;
+
+ case DataType.INTEGER:
+ bIsCompatible = (DataType.SMALLINT == _eType2)
+ || (DataType.TINYINT == _eType2)
+ || (DataType.BIT == _eType2)
+ || (DataType.BOOLEAN == _eType2);
+ break;
+ case DataType.SMALLINT:
+ bIsCompatible = (DataType.TINYINT == _eType2)
+ || (DataType.BIT == _eType2)
+ || (DataType.BOOLEAN == _eType2);
+ break;
+ case DataType.TINYINT:
+ bIsCompatible = (DataType.BIT == _eType2)
+ || (DataType.BOOLEAN == _eType2);
+ break;
+
+ case DataType.BLOB:
+ case DataType.CLOB:
+ case DataType.OBJECT:
+ bIsCompatible = (DataType.BLOB == _eType2)
+ || (DataType.CLOB == _eType2)
+ || (DataType.OBJECT == _eType2);
+ break;
+
+ default:
+ bIsCompatible = false;
+ }
+ }
+ return bIsCompatible;
+ }
+
+ public int getTypeKind() {
+ return typeKind;
+ }
+
+ public void setTypeKind(int type) throws SQLException {
+ if (!isNull() && !isStorageCompatible(type, typeKind)) {
+ switch (type) {
+ case DataType.VARCHAR:
+ case DataType.CHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ setString(getString());
+ break;
+ case DataType.BIGINT:
+ setLong(getLong());
+ break;
+
+ case DataType.FLOAT:
+ setFloat(getFloat());
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ setDouble(getDouble());
+ break;
+ case DataType.TINYINT:
+ setInt8(getInt8());
+ break;
+ case DataType.SMALLINT:
+ setInt16(getInt16());
+ break;
+ case DataType.INTEGER:
+ setInt32(getInt32());
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ setBoolean(getBoolean());
+ break;
+ case DataType.DATE:
+ setDate(getDate());
+ break;
+ case DataType.TIME:
+ setTime(getTime());
+ break;
+ case DataType.TIMESTAMP:
+ setDateTime(getDateTime());
+ break;
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ setSequence(getSequence());
+ break;
+ case DataType.BLOB:
+ case DataType.CLOB:
+ case DataType.OBJECT:
+ case DataType.OTHER:
+ setAny(getAny());
+ break;
+ default:
+ setAny(getAny());
+ //OSL_ENSURE(0,"ORowSetValue:operator==(): UNSPUPPORTED TYPE!");
+ }
+ }
+ typeKind = type;
+ }
+
+ private void free() {
+ if (!isNull()) {
+ value = null;
+ flags |= FLAG_NULL;
+ }
+ }
+
+ public Any getAny() {
+ Any any = (Any)value;
+ return new Any(any.getType(), any.getObject());
+ }
+
+ public boolean getBoolean() {
+ boolean bRet = false;
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.LONGVARCHAR:
+ if (((String)value).equals("true")) {
+ bRet = true;
+ } else if (((String)value).equals("false")) {
+ bRet = false;
+ }
+ // fall through
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ bRet = DBTypeConversion.safeParseInt((String)value) != 0;
+ break;
+ case DataType.BIGINT:
+ bRet = (long)value != 0;
+ break;
+ case DataType.FLOAT:
+ bRet = (float)value != 0.0;
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ bRet = (double)value != 0.0;
+ break;
+ case DataType.DATE:
+ case DataType.TIME:
+ case DataType.TIMESTAMP:
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ bRet = (boolean)value;
+ break;
+ case DataType.TINYINT:
+ bRet = (byte)value != 0;
+ break;
+ case DataType.SMALLINT:
+ bRet = (short)value != 0;
+ break;
+ case DataType.INTEGER:
+ bRet = (int)value != 0;
+ break;
+ default:
+ try {
+ bRet = AnyConverter.toBoolean(value);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ }
+ break;
+ }
+ }
+ return bRet;
+ }
+
+ public Date getDate() throws SQLException {
+ Date aValue = new Date();
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.LONGVARCHAR:
+ aValue = DBTypeConversion.toDate(getString());
+ break;
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.FLOAT:
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ aValue = DBTypeConversion.toDate(getDouble());
+ break;
+ case DataType.DATE:
+ Date date = (Date)value;
+ aValue.Day = date.Day;
+ aValue.Month = date.Month;
+ aValue.Year = date.Year;
+ break;
+ case DataType.TIMESTAMP:
+ DateTime dateTime = (DateTime)value;
+ aValue.Day = dateTime.Day;
+ aValue.Month = dateTime.Month;
+ aValue.Year = dateTime.Year;
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ case DataType.TINYINT:
+ case DataType.SMALLINT:
+ case DataType.INTEGER:
+ case DataType.BIGINT:
+ aValue = DBTypeConversion.toDate((double)getLong());
+ break;
+
+ case DataType.BLOB:
+ case DataType.CLOB:
+ case DataType.OBJECT:
+ default:
+ //OSL_ENSURE( false, "ORowSetValue::getDate: cannot retrieve the data!" );
+ // NO break!
+
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ case DataType.TIME:
+ aValue = DBTypeConversion.toDate(0.0);
+ break;
+ }
+ }
+ return aValue;
+
+ }
+
+ public DateTime getDateTime() throws SQLException {
+ DateTime aValue = new DateTime();
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.LONGVARCHAR:
+ aValue = DBTypeConversion.toDateTime(getString());
+ break;
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.FLOAT:
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ aValue = DBTypeConversion.toDateTime(getDouble());
+ break;
+ case DataType.DATE:
+ Date date = (Date)value;
+ aValue.Day = date.Day;
+ aValue.Month = date.Month;
+ aValue.Year = date.Year;
+ break;
+ case DataType.TIME:
+ Time time = (Time)value;
+ aValue.HundredthSeconds = time.HundredthSeconds;
+ aValue.Seconds = time.Seconds;
+ aValue.Minutes = time.Minutes;
+ aValue.Hours = time.Hours;
+ break;
+ case DataType.TIMESTAMP:
+ DateTime dateTime = (DateTime)value;
+ aValue.Year = dateTime.Year;
+ aValue.Month = dateTime.Month;
+ aValue.Day = dateTime.Day;
+ aValue.Hours = dateTime.Hours;
+ aValue.Minutes = dateTime.Minutes;
+ aValue.Seconds = dateTime.Seconds;
+ aValue.HundredthSeconds = dateTime.HundredthSeconds;
+ break;
+ default:
+ try {
+ DateTime any = AnyConverter.toObject(DateTime.class, value);
+ aValue.Year = any.Year;
+ aValue.Month = any.Month;
+ aValue.Day = any.Day;
+ aValue.Hours = any.Hours;
+ aValue.Minutes = any.Minutes;
+ aValue.Seconds = any.Seconds;
+ aValue.HundredthSeconds = any.HundredthSeconds;
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ } catch (ClassCastException classCastException) {
+ }
+ break;
+ }
+ }
+ return aValue;
+ }
+
+ public double getDouble() {
+ double nRet = 0.0;
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ nRet = DBTypeConversion.safeParseDouble((String)value);
+ break;
+ case DataType.BIGINT:
+ nRet = isSigned() ? (long)value : DBTypeConversion.unsignedLongToDouble((long)value);
+ break;
+ case DataType.FLOAT:
+ nRet = (float)value;
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ nRet = (double)value;
+ break;
+ case DataType.DATE:
+ nRet = DBTypeConversion.toDouble((Date)value);
+ break;
+ case DataType.TIME:
+ nRet = DBTypeConversion.toDouble((Time)value);
+ break;
+ case DataType.TIMESTAMP:
+ nRet = DBTypeConversion.toDouble((DateTime)value);
+ break;
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ case DataType.BLOB:
+ case DataType.CLOB:
+ //OSL_ASSERT(!"getDouble() for this type is not allowed!");
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ nRet = (boolean)value ? 1 : 0;
+ break;
+ case DataType.TINYINT:
+ nRet = isSigned() ? (byte)value : 0xff & (byte)value;
+ break;
+ case DataType.SMALLINT:
+ nRet = isSigned() ? (short)value : 0xffff & (short)value;
+ break;
+ case DataType.INTEGER:
+ nRet = isSigned() ? (int)value : 0xffffFFFFL & (int)value;
+ break;
+ default:
+ try {
+ nRet = AnyConverter.toDouble(value);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ }
+ break;
+ }
+ }
+ return nRet;
+ }
+
+ public float getFloat() {
+ float nRet = 0.0f;
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ nRet = DBTypeConversion.safeParseFloat((String)value);
+ break;
+ case DataType.BIGINT:
+ nRet = isSigned() ? (long)value : DBTypeConversion.unsignedLongToFloat((long)value);
+ break;
+ case DataType.FLOAT:
+ nRet = (float)value;
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ nRet = (float)(double)value;
+ break;
+ case DataType.DATE:
+ nRet = (float)DBTypeConversion.toDouble((Date)value);
+ break;
+ case DataType.TIME:
+ nRet = (float)DBTypeConversion.toDouble((Time)value);
+ break;
+ case DataType.TIMESTAMP:
+ nRet = (float)DBTypeConversion.toDouble((DateTime)value);
+ break;
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ case DataType.BLOB:
+ case DataType.CLOB:
+ //OSL_ASSERT(!"getDouble() for this type is not allowed!");
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ nRet = (boolean)value ? 1 : 0;
+ break;
+ case DataType.TINYINT:
+ nRet = isSigned() ? (byte)value : 0xff & (byte)value;
+ break;
+ case DataType.SMALLINT:
+ nRet = isSigned() ? (short)value : 0xffff & (short)value;
+ break;
+ case DataType.INTEGER:
+ nRet = isSigned() ? (int)value : 0xffffFFFFL & (int)value;
+ break;
+ default:
+ try {
+ nRet = AnyConverter.toFloat(value);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ }
+ break;
+ }
+ }
+ return nRet;
+ }
+
+ public byte getInt8() {
+ byte nRet = 0;
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ nRet = (byte)DBTypeConversion.safeParseInt((String)value);
+ break;
+ case DataType.BIGINT:
+ nRet = (byte)(long)value;
+ break;
+ case DataType.FLOAT:
+ nRet = (byte)(float)value;
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ nRet = (byte)(double)value;
+ break;
+ case DataType.DATE:
+ case DataType.TIME:
+ case DataType.TIMESTAMP:
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ case DataType.BLOB:
+ case DataType.CLOB:
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ nRet = (byte)((boolean)value ? 1 : 0);
+ break;
+ case DataType.TINYINT:
+ nRet = (byte)value;
+ break;
+ case DataType.SMALLINT:
+ nRet = (byte)(short)value;
+ break;
+ case DataType.INTEGER:
+ nRet = (byte)(int)value;
+ break;
+ default:
+ try {
+ nRet = AnyConverter.toByte(value);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ }
+ break;
+ }
+ }
+ return nRet;
+ }
+
+ public short getInt16() {
+ short nRet = 0;
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ nRet = (short)DBTypeConversion.safeParseInt((String)value);
+ break;
+ case DataType.BIGINT:
+ nRet = (short)(long)value;
+ break;
+ case DataType.FLOAT:
+ nRet = (short)(float)value;
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ nRet = (short)(double)value;
+ break;
+ case DataType.DATE:
+ case DataType.TIME:
+ case DataType.TIMESTAMP:
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ case DataType.BLOB:
+ case DataType.CLOB:
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ nRet = (short)((boolean)value ? 1 : 0);
+ break;
+ case DataType.TINYINT:
+ nRet = (short)(isSigned() ? (byte)value : 0xff & (byte)value);
+ break;
+ case DataType.SMALLINT:
+ nRet = (short)value;
+ break;
+ case DataType.INTEGER:
+ nRet = (short)(int)value;
+ break;
+ default:
+ try {
+ nRet = AnyConverter.toShort(value);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ }
+ break;
+ }
+ }
+ return nRet;
+ }
+
+ public int getInt32() {
+ int nRet = 0;
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ nRet = DBTypeConversion.safeParseInt((String)value);
+ break;
+ case DataType.BIGINT:
+ nRet = (int)(long)value;
+ break;
+ case DataType.FLOAT:
+ nRet = (int)(float)value;
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ nRet = (int)(double)value;
+ break;
+ case DataType.DATE:
+ nRet = DBTypeConversion.toDays((Date)value);
+ break;
+ case DataType.TIME:
+ case DataType.TIMESTAMP:
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ case DataType.BLOB:
+ case DataType.CLOB:
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ nRet = (boolean)value ? 1 : 0;
+ break;
+ case DataType.TINYINT:
+ nRet = isSigned() ? (byte)value : 0xff & (byte)value;
+ break;
+ case DataType.SMALLINT:
+ nRet = isSigned() ? (short)value : 0xffff & (short)value;
+ break;
+ case DataType.INTEGER:
+ nRet = (int)value;
+ break;
+ default:
+ try {
+ nRet = AnyConverter.toInt(value);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ }
+ break;
+ }
+ }
+ return nRet;
+ }
+
+ public long getLong() {
+ long nRet = 0;
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ nRet = DBTypeConversion.safeParseLong((String)value);
+ break;
+ case DataType.BIGINT:
+ nRet = (long)value;
+ break;
+ case DataType.FLOAT:
+ nRet = (long)(float)value;
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ nRet = (long)(double)value;
+ break;
+ case DataType.DATE:
+ nRet = DBTypeConversion.toDays((Date)value);
+ break;
+ case DataType.TIME:
+ case DataType.TIMESTAMP:
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ case DataType.BLOB:
+ case DataType.CLOB:
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ nRet = (boolean)value ? 1 : 0;
+ break;
+ case DataType.TINYINT:
+ nRet = isSigned() ? (byte)value : 0xff & (byte)value;
+ break;
+ case DataType.SMALLINT:
+ nRet = isSigned() ? (short)value : 0xffff & (short)value;
+ break;
+ case DataType.INTEGER:
+ nRet = isSigned() ? (int)value : 0xffffFFFFL & (int)value;
+ break;
+ default:
+ try {
+ nRet = AnyConverter.toInt(value);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ }
+ break;
+ }
+ }
+ return nRet;
+ }
+
+ public byte[] getSequence() throws SQLException {
+ byte[] aSeq = new byte[0];
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.OBJECT:
+ case DataType.CLOB:
+ case DataType.BLOB:
+ XInputStream xStream = null;
+ if (value != null) {
+ XBlob blob = UnoRuntime.queryInterface(XBlob.class, value);
+ if (blob != null) {
+ xStream = blob.getBinaryStream();
+ } else {
+ XClob clob = UnoRuntime.queryInterface(XClob.class, value);
+ if (clob != null) {
+ xStream = clob.getCharacterStream();
+ }
+ }
+ if (xStream != null) {
+ try {
+ try {
+ final int bytesToRead = 65535;
+ byte[][] aReadSeq = new byte[1][];
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int read;
+ do {
+ read = xStream.readBytes(aReadSeq, bytesToRead);
+ baos.write(aReadSeq[0], 0, read);
+ } while (read == bytesToRead);
+ aSeq = baos.toByteArray();
+ } finally {
+ xStream.closeInput();
+ }
+ } catch (IOException ioException) {
+ throw new SQLException(ioException.getMessage());
+ }
+ }
+ }
+ break;
+ case DataType.VARCHAR:
+ case DataType.LONGVARCHAR:
+ try {
+ aSeq = ((String)value).getBytes("UTF-16");
+ } catch (UnsupportedEncodingException unsupportedEncodingException) {
+ }
+ break;
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ aSeq = ((byte[])value).clone();
+ break;
+ default:
+ try {
+ aSeq = ((byte[])AnyConverter.toArray(value)).clone();
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ } catch (ClassCastException classCastException) {
+ }
+ break;
+ }
+ }
+ return aSeq;
+ }
+
+ public String getString() throws SQLException {
+ String aRet = "";
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ aRet = (String)value;
+ break;
+ case DataType.BIGINT:
+ aRet = isSigned() ? Long.toString((long)value) : Long.toUnsignedString((long)value);
+ break;
+ case DataType.FLOAT:
+ aRet = ((Float)value).toString();
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ aRet = ((Double)value).toString();
+ break;
+ case DataType.DATE:
+ aRet = DBTypeConversion.toDateString((Date)value);
+ break;
+ case DataType.TIME:
+ aRet = DBTypeConversion.toTimeString((Time)value);
+ break;
+ case DataType.TIMESTAMP:
+ aRet = DBTypeConversion.toDateTimeString((DateTime)value);
+ break;
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ {
+ StringBuilder sVal = new StringBuilder("0x");
+ byte[] sSeq = getSequence();
+ for (byte b : sSeq) {
+ sVal.append(String.format("%02x", Byte.toUnsignedInt(b)));
+ }
+ aRet = sVal.toString();
+ }
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ aRet = ((Boolean)value).toString();
+ break;
+ case DataType.TINYINT:
+ aRet = isSigned() ? Integer.toString((byte)value) : Integer.toUnsignedString(0xff & (byte)value);
+ break;
+ case DataType.SMALLINT:
+ aRet = isSigned() ? Integer.toString((short)value) : Integer.toUnsignedString(0xffff & (short)value);
+ break;
+ case DataType.INTEGER:
+ aRet = isSigned() ? Integer.toString((int)value) : Integer.toUnsignedString((int)value);
+ break;
+ case DataType.CLOB:
+ if (AnyConverter.isObject(value)) {
+ try {
+ XClob clob = AnyConverter.toObject(XClob.class, value);
+ if (clob != null) {
+ aRet = clob.getSubString(1, (int)clob.length());
+ }
+ } catch (ClassCastException classCastException) {
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ }
+ }
+ break;
+ default:
+ try {
+ aRet = AnyConverter.toString(value);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ }
+ break;
+ }
+ }
+ return aRet;
+ }
+
+ public Time getTime() throws SQLException {
+ Time aValue = new Time();
+ if (!isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.LONGVARCHAR:
+ aValue = DBTypeConversion.toTime(getString());
+ break;
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ aValue = DBTypeConversion.toTime(getDouble());
+ break;
+ case DataType.FLOAT:
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ aValue = DBTypeConversion.toTime(getDouble());
+ break;
+ case DataType.TIMESTAMP:
+ DateTime pDateTime = (DateTime)value;
+ aValue.HundredthSeconds = pDateTime.HundredthSeconds;
+ aValue.Seconds = pDateTime.Seconds;
+ aValue.Minutes = pDateTime.Minutes;
+ aValue.Hours = pDateTime.Hours;
+ break;
+ case DataType.TIME:
+ Time time = (Time)value;
+ aValue.Hours = time.Hours;
+ aValue.Minutes = time.Minutes;
+ aValue.Seconds = time.Seconds;
+ aValue.HundredthSeconds = time.HundredthSeconds;
+ break;
+ default:
+ try {
+ aValue = AnyConverter.toObject(Time.class, value);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ } catch (ClassCastException classCastException) {
+ }
+ break;
+ }
+ }
+ return aValue;
+ }
+
+ public void setAny(Any value) {
+ flags &= ~FLAG_NULL;
+ this.value = new Any(value.getType(), value.getObject());
+ typeKind = DataType.OBJECT;
+ }
+
+ public void setBoolean(boolean value) {
+ flags &= ~FLAG_NULL;
+ this.value = value;
+ typeKind = DataType.BIT;
+ }
+
+ public void setDate(Date date) {
+ flags &= ~FLAG_NULL;
+ this.value = new Date(date.Day, date.Month, date.Year);
+ typeKind = DataType.DATE;
+ }
+
+ public void setDateTime(DateTime value) {
+ flags &= ~FLAG_NULL;
+ this.value = new DateTime(value.HundredthSeconds, value.Seconds, value.Minutes, value.Hours,
+ value.Day, value.Minutes, value.Year);
+ typeKind = DataType.TIMESTAMP;
+ }
+
+ public void setDouble(double value) {
+ flags &= ~FLAG_NULL;
+ this.value = value;
+ typeKind = DataType.DOUBLE;
+ }
+
+ public void setFloat(float value) {
+ flags &= ~FLAG_NULL;
+ this.value = value;
+ typeKind = DataType.FLOAT;
+ }
+
+ public void setInt8(byte value) {
+ flags &= ~FLAG_NULL;
+ this.value = value;
+ typeKind = DataType.TINYINT;
+ }
+
+ public void setInt16(short value) {
+ flags &= ~FLAG_NULL;
+ this.value = value;
+ typeKind = DataType.SMALLINT;
+ }
+
+ public void setInt32(int value) {
+ flags &= ~FLAG_NULL;
+ this.value = value;
+ typeKind = DataType.INTEGER;
+ }
+
+ public void setLong(long value) {
+ flags &= ~FLAG_NULL;
+ this.value = value;
+ typeKind = DataType.BIGINT;
+ }
+
+ public void setSequence(byte[] value) {
+ flags &= ~FLAG_NULL;
+ this.value = value.clone();
+ typeKind = DataType.LONGVARBINARY;
+ }
+
+ public void setString(String value) {
+ flags &= ~FLAG_NULL;
+ this.value = value;
+ typeKind = DataType.VARCHAR;
+ }
+
+ public void setTime(Time value) {
+ flags &= ~FLAG_NULL;
+ this.value = new Time(value.Hours, value.Minutes, value.Seconds, value.HundredthSeconds);
+ typeKind = DataType.TIME;
+ }
+
+ public Object makeAny() {
+ Object rValue = new Any(Type.VOID, null);
+ if(isBound() && !isNull()) {
+ switch (getTypeKind()) {
+ case DataType.CHAR:
+ case DataType.VARCHAR:
+ case DataType.DECIMAL:
+ case DataType.NUMERIC:
+ case DataType.LONGVARCHAR:
+ rValue = value;
+ break;
+ case DataType.BIGINT:
+ rValue = value;
+ break;
+ case DataType.FLOAT:
+ rValue = value;
+ break;
+ case DataType.DOUBLE:
+ case DataType.REAL:
+ rValue = value;
+ break;
+ case DataType.DATE:
+ Date date = (Date)value;
+ Date dateOut = new Date();
+ dateOut.Day = date.Day;
+ dateOut.Month = date.Month;
+ dateOut.Year = date.Year;
+ rValue = dateOut;
+ break;
+ case DataType.TIME:
+ Time time = (Time)value;
+ Time timeOut = new Time();
+ timeOut.Hours = time.Hours;
+ timeOut.Minutes = time.Minutes;
+ timeOut.Seconds = time.Seconds;
+ timeOut.HundredthSeconds = time.HundredthSeconds;
+ rValue = timeOut;
+ break;
+ case DataType.TIMESTAMP:
+ DateTime dateTime = (DateTime)value;
+ DateTime dateTimeOut = new DateTime(dateTime.HundredthSeconds, dateTime.Seconds, dateTime.Minutes, dateTime.Hours,
+ dateTime.Day, dateTime.Minutes, dateTime.Year);
+ rValue = dateTimeOut;
+ break;
+ case DataType.BINARY:
+ case DataType.VARBINARY:
+ case DataType.LONGVARBINARY:
+ rValue = ((byte[])value).clone();
+ break;
+ case DataType.BLOB:
+ case DataType.CLOB:
+ case DataType.OBJECT:
+ case DataType.OTHER:
+ rValue = getAny();
+ break;
+ case DataType.BIT:
+ case DataType.BOOLEAN:
+ rValue = (boolean)value;
+ break;
+ case DataType.TINYINT:
+ rValue = (byte)value;
+ break;
+ case DataType.SMALLINT:
+ rValue = (short)value;
+ break;
+ case DataType.INTEGER:
+ rValue = (int)value;
+ break;
+ default:
+ rValue = getAny();
+ break;
+ }
+ }
+ return rValue;
+ }
+}
+
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/Osl.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/Osl.java
new file mode 100644
index 000000000000..8ace907d77e0
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/Osl.java
@@ -0,0 +1,36 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+public class Osl {
+ public static void ensure(boolean condition, String message) {
+ if (!condition) {
+ throw new com.sun.star.uno.RuntimeException(message);
+ }
+ }
+
+ public static void ensure(Object reference, String message) {
+ if (reference == null) {
+ throw new com.sun.star.uno.RuntimeException(message);
+ }
+ }
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/PropertyIds.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/PropertyIds.java
new file mode 100644
index 000000000000..0e59e0d9b8d4
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/PropertyIds.java
@@ -0,0 +1,95 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+public enum PropertyIds {
+ QUERYTIMEOUT(1, "QueryTimeOut"),
+ MAXFIELDSIZE(2, "MaxFieldSize"),
+ MAXROWS(3, "MaxRows"),
+ CURSORNAME(4, "CursorName"),
+ RESULTSETCONCURRENCY(5, "ResultSetConcurrency"),
+ RESULTSETTYPE(6, "ResultSetType"),
+ FETCHDIRECTION(7, "FetchDirection"),
+ FETCHSIZE(8, "FetchSize"),
+ ESCAPEPROCESSING(9, "EscapeProcessing"),
+ USEBOOKMARKS (10, "UseBookmarks"),
+ // Column
+ NAME (11, "Name"),
+ TYPE (12, "Type"),
+ TYPENAME (13, "TypeName"),
+ PRECISION (14, "Precision"),
+ SCALE (15, "Scale"),
+ ISNULLABLE (16, "IsNullable"),
+ ISAUTOINCREMENT (17, "IsAutoIncrement"),
+ ISROWVERSION (18, "IsRowVersion"),
+ DESCRIPTION (19, "Description"),
+ DEFAULTVALUE (20, "DefaultValue"),
+ REFERENCEDTABLE (21, "ReferencedTable"),
+ UPDATERULE (22, "UpdateRule"),
+ DELETERULE (23, "DeleteRule"),
+ CATALOG (24, "Catalog"),
+ ISUNIQUE (25, "IsUnique"),
+ ISPRIMARYKEYINDEX (26, "IsPrimaryKeyIndex"),
+ ISCLUSTERED (27, "IsClustered"),
+ ISASCENDING (28, "IsAscending"),
+ SCHEMANAME (29, "SchemaName"),
+ CATALOGNAME (30, "CatalogName"),
+ COMMAND (31, "CheckOption"),
+ CHECKOPTION (32, "Password"),
+ PASSWORD (33, "RelatedColumn"),
+ RELATEDCOLUMN (34, ""),
+ FUNCTION (35, "Function"),
+ TABLENAME (36, "TableName"),
+ REALNAME (37, "RealName"),
+ DBASEPRECISIONCHANGED (38, "DbasePrecisionChanged"),
+ ISCURRENCY (39, "IsCurrency"),
+ ISBOOKMARKABLE (40, "IsBookmarkable"),
+ INVALID_INDEX (41, ""),
+ HY010 (43, "HY010"),
+ LABEL (44, "Label"),
+ DELIMITER (45, "/"),
+ FORMATKEY (46, "FormatKey"),
+ LOCALE (47, "Locale"),
+ IM001 (48, ""),
+ AUTOINCREMENTCREATION (49, "AutoIncrementCreation"),
+ PRIVILEGES (50, "Privileges"),
+ HAVINGCLAUSE (51, "HavingClause"),
+ ISSIGNED (52, "IsSigned"),
+ AGGREGATEFUNCTION (53, "AggregateFunction"),
+ ISSEARCHABLE (54, "IsSearchable"),
+ APPLYFILTER (55, "ApplyFilter"),
+ FILTER (56, "Filter"),
+ MASTERFIELDS (57, "MasterFields"),
+ DETAILFIELDS (58, "DetailFields"),
+ FIELDTYPE (59, "FieldType"),
+ VALUE (60, "Value"),
+ ACTIVE_CONNECTION (61, "ActiveConnection");
+
+
+ PropertyIds(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public final int id;
+ public final String name;
+}
diff --git a/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/StandardSQLState.java b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/StandardSQLState.java
new file mode 100644
index 000000000000..3d6990f4ad6a
--- /dev/null
+++ b/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/StandardSQLState.java
@@ -0,0 +1,58 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+package com.sun.star.sdbcx.comp.postgresql.util;
+
+public enum StandardSQLState {
+ SQL_WRONG_PARAMETER_NUMBER("07001"),
+ SQL_INVALID_DESCRIPTOR_INDEX("07009"),
+ SQL_UNABLE_TO_CONNECT("08001"),
+ SQL_NUMERIC_OUT_OF_RANGE("22003"),
+ SQL_INVALID_DATE_TIME("22007"),
+ SQL_INVALID_CURSOR_STATE("24000"),
+ SQL_TABLE_OR_VIEW_EXISTS("42S01"),
+ SQL_TABLE_OR_VIEW_NOT_FOUND("42S02"),
+ SQL_INDEX_EXISTS("42S11"),
+ SQL_INDEX_NOT_FOUND("42S12"),
+ SQL_COLUMN_EXISTS("42S21"),
+ SQL_COLUMN_NOT_FOUND("42S22"),
+ SQL_GENERAL_ERROR("HY000"),
+ SQL_INVALID_SQL_DATA_TYPE("HY004"),
+ SQL_OPERATION_CANCELED("HY008"),
+ SQL_FUNCTION_SEQUENCE_ERROR("HY010"),
+ SQL_INVALID_CURSOR_POSITION("HY109"),
+ SQL_INVALID_BOOKMARK_VALUE("HY111"),
+ SQL_FEATURE_NOT_IMPLEMENTED("HYC00"),
+ SQL_FUNCTION_NOT_SUPPORTED("IM001"),
+ SQL_CONNECTION_DOES_NOT_EXIST("08003"),
+ SQL_ERROR_UNSPECIFIED("");
+
+
+ private String text;
+
+ private StandardSQLState(String text) {
+ this.text = text;
+ }
+
+ public String text() {
+ return text;
+ }
+}
diff --git a/connectivity/prj/build.lst b/connectivity/prj/build.lst
index a16d486d3358..249cf339c84a 100644
--- a/connectivity/prj/build.lst
+++ b/connectivity/prj/build.lst
@@ -1,7 +1,8 @@
-cn connectivity : shell L10N:l10n comphelper SO:moz_prebuilt svl UNIXODBC:unixODBC unoil javaunohelper HSQLDB:hsqldb qadevOOo officecfg LIBXSLT:libxslt NULL
+cn connectivity : shell L10N:l10n comphelper SO:moz_prebuilt svl UNIXODBC:unixODBC unoil javaunohelper HSQLDB:hsqldb qadevOOo officecfg LIBXSLT:libxslt apache-commons NULL
cn connectivity usr1 - all cn_mkout NULL
cn connectivity\inc nmake - all cn_inc NULL
cn connectivity\java\sdbc_hsqldb nmake - all cn_jhsqldbdb cn_hsqldb cn_inc NULL
+cn connectivity\java\sdbc_postgresql nmake - all cn_postgresqldb cn_dbtools cn_inc NULL
cn connectivity\source\commontools nmake - all cn_cmtools cn_parse cn_inc NULL
cn connectivity\source\manager nmake - all cn_manager cn_dbtools cn_inc NULL
cn connectivity\source\cpool nmake - all cn_cpool cn_dbtools cn_inc NULL
diff --git a/connectivity/prj/d.lst b/connectivity/prj/d.lst
index 394bba416eba..5fa4e80ab4a6 100644
--- a/connectivity/prj/d.lst
+++ b/connectivity/prj/d.lst
@@ -21,6 +21,7 @@
..\source\drivers\mysql\*.xml %_DEST%\xml%_EXT%\*.xml
..\%__SRC%\class\*.jar %_DEST%\bin%_EXT%\*.jar
..\%__SRC%\class\sdbc_hsqldb\*.jar %_DEST%\bin%_EXT%\*.jar
+..\%__SRC%\class\sdbc_postgresql\*.jar %_DEST%\bin%_EXT%\*.jar
mkdir: %_DEST%\inc%_EXT%\connectivity
mkdir: %_DEST%\inc%_EXT%\connectivity\sdbcx
@@ -46,4 +47,5 @@ mkdir: %_DEST%\xml%_EXT%\registry\spool\DataAccess
..\%__SRC%\misc\macab1.component %_DEST%\xml%_EXT%\macab1.component
..\%__SRC%\misc\mysql.component %_DEST%\xml%_EXT%\mysql.component
..\%__SRC%\misc\odbc.component %_DEST%\xml%_EXT%\odbc.component
+..\%__SRC%\misc\postgresql.component %_DEST%\xml%_EXT%\postgresql.component
..\%__SRC%\misc\sdbc2.component %_DEST%\xml%_EXT%\sdbc2.component
diff --git a/connectivity/target.pmk b/connectivity/target.pmk
index 9bb63cc914a9..50e5b639d273 100644
--- a/connectivity/target.pmk
+++ b/connectivity/target.pmk
@@ -21,7 +21,8 @@
-.INCLUDE : target.mk
+#.INCLUDE : target.mk
+.INCLUDE : ant.mk
COMPONENT_CONFIG_SCHEMA*=$(TARGET).xcs