diff options
Diffstat (limited to 'wizards/com/sun/star/wizards/db/TypeInspector.java')
-rw-r--r-- | wizards/com/sun/star/wizards/db/TypeInspector.java | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/wizards/com/sun/star/wizards/db/TypeInspector.java b/wizards/com/sun/star/wizards/db/TypeInspector.java new file mode 100644 index 000000000000..1f22801fd8c5 --- /dev/null +++ b/wizards/com/sun/star/wizards/db/TypeInspector.java @@ -0,0 +1,465 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package com.sun.star.wizards.db; + +import java.util.Vector; + +import com.sun.star.beans.XPropertySet; +import com.sun.star.sdbc.ColumnSearch; +import com.sun.star.sdbc.ColumnValue; +import com.sun.star.sdbc.DataType; +import com.sun.star.sdbc.SQLException; +import com.sun.star.sdbc.XResultSet; +import com.sun.star.sdbc.XRow; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.wizards.common.JavaTools; + +public class TypeInspector +{ + + private String[] sDataTypeNames; + private int[] nDataTypeInfos; + private int[] nPrecisionInfos; + private int[] nNullableInfos; + private int[] nSearchables; + private boolean[] bisAutoIncrementableInfos; + private int[] nMinScaleInfos; + private int[] nMaxScaleInfos; + private int[] nNumericFallBackList = new int[] + { + DataType.INTEGER, DataType.FLOAT, DataType.REAL, DataType.DOUBLE, DataType.NUMERIC, DataType.DECIMAL + }; + final int INVALID = 999999; + XResultSet xResultSet; + + public class TypeInfo + { + + public int nDataType; + public String sDataTypeName; + public boolean bisAutoIncrementable; + + public TypeInfo(int _nDataType, String _sDataTypeName, boolean _bisAutoIncrementable) + { + nDataType = _nDataType; + sDataTypeName = _sDataTypeName; + bisAutoIncrementable = _bisAutoIncrementable; + } + } + + public TypeInspector(XResultSet _xResultSet) + { + try + { + xResultSet = _xResultSet; + Vector<String> aTypeNameVector = new Vector<String>(); + Vector<Integer> aTypeVector = new Vector<Integer>(); + Vector<Integer> aNullableVector = new Vector<Integer>(); + Vector<Boolean> aAutoIncrementVector = new Vector<Boolean>(); + Vector<Integer> aPrecisionVector = new Vector<Integer>(); + Vector<Integer> aMinScaleVector = new Vector<Integer>(); + Vector<Integer> aMaxScaleVector = new Vector<Integer>(); + Vector<Integer> aSearchableVector = new Vector<Integer>(); + // Integer[] aIntegerDataTypes = null; +// XResultSet xResultSet = xDBMetaDagetTypeInfo(); + XRow xRow = (XRow) UnoRuntime.queryInterface(XRow.class, xResultSet); + while (xResultSet.next()) + { + aTypeNameVector.addElement(new String(xRow.getString(1))); + aTypeVector.addElement(new Integer(xRow.getShort(2))); + aPrecisionVector.addElement(new Integer(xRow.getInt(3))); + aNullableVector.addElement(new Integer(xRow.getShort(7))); + aSearchableVector.addElement(new Integer(xRow.getShort(9))); + aAutoIncrementVector.addElement(new Boolean(xRow.getBoolean(12))); + aMinScaleVector.addElement(new Integer(xRow.getShort(14))); + aMaxScaleVector.addElement(new Integer(xRow.getShort(15))); + + } + sDataTypeNames = new String[aTypeNameVector.size()]; + aTypeNameVector.toArray(sDataTypeNames); + nDataTypeInfos = JavaTools.IntegerTointList(aTypeVector); + nNullableInfos = JavaTools.IntegerTointList(aNullableVector); + nSearchables = JavaTools.IntegerTointList(aSearchableVector); + bisAutoIncrementableInfos = JavaTools.BooleanTobooleanList(aAutoIncrementVector); + nPrecisionInfos = JavaTools.IntegerTointList(aPrecisionVector); + nMinScaleInfos = JavaTools.IntegerTointList(aMinScaleVector); + nMaxScaleInfos = JavaTools.IntegerTointList(aMaxScaleVector); + } + catch (SQLException e) + { + e.printStackTrace(System.out); + } + } + + public int getScale(XPropertySet _xColPropertySet) + { + try + { + int i = getDataTypeIndex(_xColPropertySet, false); + int nScale = AnyConverter.toInt(_xColPropertySet.getPropertyValue("Scale")); + if (i == -1) + { + return nScale; + } + if (nScale > nMaxScaleInfos[i]) + { + return nMaxScaleInfos[i]; + } + else if (nScale < nMinScaleInfos[i]) + { + return nMinScaleInfos[i]; + } + else + { + return nScale; + } + } + catch (Exception e) + { + e.printStackTrace(System.out); + return 0; + } + } + + public int getNullability(XPropertySet _xColPropertySet, int _nNullable) + { + int i = getDataTypeIndex(_xColPropertySet, false); + if (i == -1) + { + return ColumnValue.NO_NULLS; + } + int nNullable = _nNullable; + if (nNullable == ColumnValue.NULLABLE) + { + return nNullableInfos[i]; //probably nullability is not allowed + } + return nNullable; + } + + public int getNullability(XPropertySet _xColPropertySet) + { + try + { + int i = getDataTypeIndex(_xColPropertySet, false); + if (i == -1) + { + return ColumnValue.NO_NULLS; + } + int nNullable = AnyConverter.toInt(_xColPropertySet.getPropertyValue("IsNullable")); + if (nNullable == ColumnValue.NULLABLE) + { + return nNullableInfos[i]; + } + return nNullable; + } + catch (Exception e) + { + e.printStackTrace(System.out); + } + return ColumnValue.NO_NULLS; + } + + public boolean isColumnOrderable(XPropertySet _xColPropertySet) + { + int i = getDataTypeIndex(_xColPropertySet, false); + if (i > -1) + { + return (nSearchables[i] != ColumnSearch.NONE); + } + else + { + return false; + } + } + + public int isNullable(XPropertySet _xColPropertySet) + { + int i = getDataTypeIndex(_xColPropertySet, false); + if (i > -1) + { + return nNullableInfos[i]; + } + else + { + return ColumnValue.NO_NULLS; + } + } + + private int getDataTypeIndex(XPropertySet _xColPropertySet, boolean _bCheckNumericAttributes) + { + try + { + int nPrecision = -1; + int nScale = -1; + int nDataType = AnyConverter.toInt(_xColPropertySet.getPropertyValue("Type")); + String sTypeName = AnyConverter.toString(_xColPropertySet.getPropertyValue("TypeName")); + if (_bCheckNumericAttributes) + { + nPrecision = AnyConverter.toInt(_xColPropertySet.getPropertyValue("Precision")); + nScale = AnyConverter.toInt(_xColPropertySet.getPropertyValue("Scale")); + } + boolean bleaveloop = false; + int startindex = 0; + while (!bleaveloop) + { + int i = JavaTools.FieldInIntTable(nDataTypeInfos, nDataType, startindex); + startindex = i + 1; + bleaveloop = (i < 0); + if (!bleaveloop) + { + if (sTypeName.equals(sDataTypeNames[i])) + { + if (_bCheckNumericAttributes) + { + if (nPrecision <= nPrecisionInfos[i]) + { + if ((nScale >= nMinScaleInfos[i]) && (nScale <= nMinScaleInfos[i])) + { + return i; + } + } + } + else + { + return i; + } + } + } + } + } + catch (Exception e) + { + e.printStackTrace(System.out); + } + return -1; + } + + public boolean supportsDataType(int _curDataType) + { + return (JavaTools.FieldInIntTable(nDataTypeInfos, _curDataType) > -1); + } + + public int getLastConversionFallbackDataType() + { + if (supportsDataType(DataType.VARCHAR)) + { + return DataType.VARCHAR; + } + else + { + return DataType.LONGVARCHAR; + } + } + + /** + * an empty string is returned when no appropriate Typename can be found + * finds the first TypeName of the passed datatype. + * @param _curDataType + * @return + */ + public String getDefaultTypeName(int _curDataType, Integer precision) + { + String ret = ""; + for (int i = 0; i < nDataTypeInfos.length; i++) + { + if (nDataTypeInfos[i] == _curDataType) + { +// System.out.println( "Desired prec " + precision + ",nPrecisionInfos[i]="+nPrecisionInfos[i] + ",sDataTypeNames[i]="+sDataTypeNames[i] ); + + if (precision == null || nPrecisionInfos[i] >= precision.intValue()) + { + ret = sDataTypeNames[i]; // this fits best ! + break; + } + else if (ret.length() == 0) + { + // in case we dont find anything else, we at return a typename + // with the correct class + ret = sDataTypeNames[i]; + } + } + } +// System.out.println( "_curDataType="+_curDataType+",precision="+precision+",ret="+ + return ret; + } + + public int getDataType(String _sTypeName) + { + int i = JavaTools.FieldInList(sDataTypeNames, _sTypeName); + if (i > -1) + { + return nDataTypeInfos[i]; + } + else + { + return getLastConversionFallbackDataType(); + } + } + + public int convertDataType(int _curDataType) + { + int retDataType = _curDataType; + if (!supportsDataType(_curDataType)) + { + switch (_curDataType) + { + case DataType.BIT: + retDataType = convertDataType(DataType.BOOLEAN); + break; + case DataType.BOOLEAN: + retDataType = convertDataType(DataType.BIT); + break; + case DataType.TINYINT: + retDataType = convertDataType(DataType.SMALLINT); + break; + case DataType.SMALLINT: + retDataType = convertDataType(DataType.INTEGER); + break; + case DataType.INTEGER: + retDataType = convertDataType(DataType.FLOAT); + break; + case DataType.FLOAT: + retDataType = convertDataType(DataType.REAL); + break; + case DataType.DATE: + case DataType.TIME: + retDataType = convertDataType(DataType.TIMESTAMP); + break; + case DataType.TIMESTAMP: + case DataType.REAL: + case DataType.BIGINT: + retDataType = convertDataType(DataType.DOUBLE); + break; + case DataType.DOUBLE: + retDataType = convertDataType(DataType.NUMERIC); + break; + case DataType.NUMERIC: + retDataType = convertDataType(DataType.DECIMAL); + break; + case DataType.DECIMAL: + if (supportsDataType(DataType.DOUBLE)) + { + retDataType = convertDataType(DataType.DOUBLE); + } + else if (supportsDataType(DataType.NUMERIC)) + { + retDataType = DataType.NUMERIC; + } + else + { + retDataType = getLastConversionFallbackDataType(); + } + break; + case DataType.VARCHAR: + retDataType = getLastConversionFallbackDataType(); + break; + default: + retDataType = getLastConversionFallbackDataType(); + } + } + return retDataType; + } + + public int getAutoIncrementIndex(XPropertySet _xColPropertySet) + { + try + { + boolean bleaveloop = false; + int startindex = 0; + int curDataType = ((Integer) _xColPropertySet.getPropertyValue("Type")).intValue(); + while (!bleaveloop) + { + int i = JavaTools.FieldInIntTable(nDataTypeInfos, curDataType, startindex); + startindex = i + 1; + bleaveloop = (i == -1); + if (!bleaveloop) + { + if (bisAutoIncrementableInfos[i]) + { + return nDataTypeInfos[i]; + } + } + } + } + catch (Exception e) + { + e.printStackTrace(System.out); + } + return INVALID; + + } + + public boolean isAutoIncrementable(XPropertySet _xColPropertySet) + { + return (getAutoIncrementIndex(_xColPropertySet) != INVALID); + } + + /** finds the first available DataType that can be used as a primary key in a table. + * @return The first datatype that also supports Autoincrmentation is taken according to the following list: + *1) INTEGER + *2) FLOAT + *3) REAL + *4) DOUBLE + *5) NUMERIC + *6) DECIMAL * + * If no appropriate datatype is found ther first available numeric type after DataType.INTEGER + * according to the 'convertDataType' method is returned + */ + /**TODO the fallback order is the same as implemented in the method 'convertDataType'. + * It's not very elegant to have the same intelligence + * on several spots in the class!! + * + */ + public TypeInfo findAutomaticPrimaryKeyType() + { + int nDataType; + for (int n = 0; n < this.nNumericFallBackList.length; n++) + { + nDataType = nNumericFallBackList[n]; + boolean bleaveloop = false; + int startindex = 0; + while (!bleaveloop) + { + int i = JavaTools.FieldInIntTable(nDataTypeInfos, nDataType, startindex); + bleaveloop = (i < 0); + if (!bleaveloop) + { + if (this.bisAutoIncrementableInfos[i]) + { + return new TypeInfo(nDataType, this.sDataTypeNames[i], true); + } + startindex = i + 1; + } + startindex = i + 1; + } + } + // As Autoincrementation is not supported for any numeric datatype we take the first available numeric Type; + nDataType = convertDataType(DataType.INTEGER); + return new TypeInfo(nDataType, getDefaultTypeName(nDataType, null), false); + } +} |