Added: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DbTools.java URL: http://svn.apache.org/viewvc/openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DbTools.java?rev=1805579&view=auto ============================================================================== --- openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DbTools.java (added) +++ openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DbTools.java Sun Aug 20 19:16:28 2017 @@ -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); + } + } + } +}
Propchange: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/DbTools.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameAccessAdapter.java URL: http://svn.apache.org/viewvc/openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameAccessAdapter.java?rev=1805579&view=auto ============================================================================== --- openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameAccessAdapter.java (added) +++ openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameAccessAdapter.java Sun Aug 20 19:16:28 2017 @@ -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(); + } + } +} Propchange: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameAccessAdapter.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameContainerAdapter.java URL: http://svn.apache.org/viewvc/openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameContainerAdapter.java?rev=1805579&view=auto ============================================================================== --- openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameContainerAdapter.java (added) +++ openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameContainerAdapter.java Sun Aug 20 19:16:28 2017 @@ -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); + } + } +} Propchange: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/MapToXNameContainerAdapter.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ORowSetValue.java URL: http://svn.apache.org/viewvc/openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ORowSetValue.java?rev=1805579&view=auto ============================================================================== --- openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ORowSetValue.java (added) +++ openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ORowSetValue.java Sun Aug 20 19:16:28 2017 @@ -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; + } +} + Propchange: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/ORowSetValue.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/Osl.java URL: http://svn.apache.org/viewvc/openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/Osl.java?rev=1805579&view=auto ============================================================================== --- openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/Osl.java (added) +++ openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/Osl.java Sun Aug 20 19:16:28 2017 @@ -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); + } + } +} Propchange: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/Osl.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/PropertyIds.java URL: http://svn.apache.org/viewvc/openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/PropertyIds.java?rev=1805579&view=auto ============================================================================== --- openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/PropertyIds.java (added) +++ openoffice/trunk/main/connectivity/java/sdbc_postgresql/src/com/sun/star/sdbcx/comp/postgresql/util/PropertyIds.java Sun Aug 20 19:16:28 2017 @@ -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; +}