All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tentackle.sql.metadata.ColumnMetaData Maven / Gradle / Ivy

There is a newer version: 21.16.1.0
Show newest version
/*
 * Tentackle - http://www.tentackle.org.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.tentackle.sql.metadata;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;
import org.tentackle.common.BasicStringHelper;
import org.tentackle.sql.Backend;
import org.tentackle.sql.SqlType;


/**
 * Meta data for a column
 *
 * @author harald
 */
public class ColumnMetaData {

  // properties the backend may not support
  private static final String SUPPORTS_AUTOINCREMENT = "supportsAutoIncrement";
  private static final String SUPPORTS_GENERATED = "supportsGenerated";


  private final TableMetaData tableMetaData;    // the table this column belongs to
  private String columnName;                    // the column columnName
  private String comment;                       // the comment
  private int type;                             // the type code from java.sql.Types
  private String typeName;                      // backend-specific type columnName
  private int size;                             // the size / length (for ex. in VARCHAR)
  private int scale;                            // the scale (for ex. DECIMAL)
  private String defaultValue;                  // column default, null = none
  private boolean nullable;                     // true if column may contain nulls
  private boolean generated;                    // true if column is generated by the backend
  private boolean autoIncrement;                // true if column is autoincremented by the backend


  /**
   * Creates column meta data.
   *
   * @param tableMetaData the table meta data this column belongs to
   */
  public ColumnMetaData(TableMetaData tableMetaData) {
    this.tableMetaData = tableMetaData;
  }


  /**
   * Gets the table meta data.
   *
   * @return the table this column belongs to
   */
  public TableMetaData getTableMetaData() {
    return tableMetaData;
  }


  /**
   * Sets up the column from the database meta data result.
   *
   * @param resultSet the column result set
   * @throws SQLException the processing the result set failed
   */
  public void setupColumnFromMetaData(ResultSet resultSet) throws SQLException {
    columnName = BasicStringHelper.toLower(resultSet.getString("COLUMN_NAME"));
    comment = resultSet.getString("REMARKS");
    size = resultSet.getInt("COLUMN_SIZE");
    scale = resultSet.getShort("DECIMAL_DIGITS");
    nullable = resultSet.getInt("NULLABLE") == DatabaseMetaData.columnNullable;
    type = resultSet.getInt("DATA_TYPE");
    typeName = resultSet.getString("TYPE_NAME");
    defaultValue = resultSet.getString("COLUMN_DEF");

    // optional features
    if (isSupported(SUPPORTS_GENERATED)) {
      try {
        autoIncrement = Objects.equals("YES", resultSet.getString("IS_AUTOINCREMENT"));
      }
      catch (SQLException sqx) {
        setSupported(SUPPORTS_GENERATED, false);
      }
    }
    if (isSupported(SUPPORTS_GENERATED)) {
      try {
        generated = Objects.equals("YES", resultSet.getString("IS_GENERATEDCOLUMN"));
      }
      catch (SQLException sqx) {
        setSupported(SUPPORTS_GENERATED, false);
      }
    }

    validate();
  }


  /**
   * Gets the columnName of the column.
   *
   * @return the columnName (always in lowercase)
   */
  public String getColumnName() {
    return columnName;
  }

  /**
   * Sets the column name.
   *
   * @param columnName the column name
   */
  public void setColumnName(String columnName) {
    this.columnName = columnName;
  }

  /**
   * Gets the comment.
   *
   * @return the comment, null if none
   */
  public String getComment() {
    return comment;
  }

  /**
   * Sets the comment.
   *
   * @param comment the comment
   */
  public void setComment(String comment) {
    this.comment = comment;
  }

  /**
   * Gets the column's type.
   *
   * @return the type
   * @see java.sql.Types
   */
  public int getType() {
    return type;
  }

  /**
   * Sets the type.
   *
   * @param type the type
   */
  public void setType(int type) {
    this.type = type;
  }

  /**
   * Gets the backend-specific type columnName.
   *
   * @return the type columnName
   */
  public String getTypeName() {
    return typeName;
  }

  /**
   * Sets the type name.
   *
   * @param typeName the type name
   */
  public void setTypeName(String typeName) {
    this.typeName = typeName;
  }

  /**
   * Gets the column's size.
   *
   * @return the size
   */
  public int getSize() {
    return size;
  }

  /**
   * Sets the size.
   *
   * @param size the size
   */
  public void setSize(int size) {
    this.size = size;
  }

  /**
   * Gets the numeric scale.
   *
   * @return the scale
   */
  public int getScale() {
    return scale;
  }

  /**
   * Sets the scale.
   *
   * @param scale the scale
   */
  public void setScale(int scale) {
    this.scale = scale;
  }

  /**
   * Gets the column's default.
   *
   * @return the default value
   */
  public String getDefaultValue() {
    return defaultValue;
  }

  /**
   * Sets the default value.
   *
   * @param defaultValue the default value
   */
  public void setDefaultValue(String defaultValue) {
    this.defaultValue = defaultValue;
  }


  /**
   * Returns whether column is nullable.
   *
   * @return true if nullable
   */
  public boolean isNullable() {
    return nullable;
  }

  /**
   * Sets whether column is nullable.
   *
   * @param nullable true if nullable
   */
  public void setNullable(boolean nullable) {
    this.nullable = nullable;
  }

  /**
   * Returns whether column is generated by the backend.
   *
   * @return true if generated
   */
  public boolean isGenerated() {
    return generated;
  }

  /**
   * Sets whether column is generated by the backend.
   *
   * @param generated if generated
   */
  public void setGenerated(boolean generated) {
    this.generated = generated;
  }

  /**
   * Returns whether column is auto-incremented by the backend.
   *
   * @return true if autoincremented
   */
  public boolean isAutoIncrement() {
    return autoIncrement;
  }

  /**
   * Sets whether column is auto-incremented by the backend.
   *
   * @param autoIncrement true if autoincremented
   */
  public void setAutoIncrement(boolean autoIncrement) {
    this.autoIncrement = autoIncrement;
  }

  /**
   * Checks whether colunm's type matches given SqlType according to the backend.
   *
   * @param sqlType the sqltype
   * @return true if matches
   */
  public boolean matchesSqlType(SqlType sqlType) {
    Backend backend = tableMetaData.getModelMetaData().getBackend();
    SqlType[] possibleSqlTypes = backend.jdbcTypeToSqlType(type, size, scale);
    for (SqlType possibleType: possibleSqlTypes) {
      if (sqlType == possibleType) {
        return true;
      }
    }
    return false;
  }


  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(columnName);
    buf.append(" ");
    buf.append(MetaDataHelper.jdbcTypeToString(type));
    if (size > 0) {
      buf.append("(");
      buf.append(size);
      if (scale > 0) {
        buf.append(",");
        buf.append(scale);
      }
      buf.append(")");
    }
    if (!nullable) {
      buf.append(" NOT NULL");
    }
    if (defaultValue != null) {
      buf.append(" DEFAULT ");
      buf.append(defaultValue);
    }
    if (autoIncrement) {
      buf.append(" AUTOINCREMENT");
    }
    buf.append(" -- ");
    buf.append(typeName);
    if (generated) {
      buf.append(", GENERATED");
    }
    return buf.toString();
  }


  /**
   * Validates and postprocesses the column data.
   */
  public void validate() {
    if (comment != null && comment.isEmpty()) {
      comment = null;
    }
    if (defaultValue != null && defaultValue.isEmpty()) {
      defaultValue = null;
    }
  }


  /**
   * Returns whether a feature is supported by the backend.
   *
   * @param property the feature
   * @return true if supported or not known whether supported or not, false if known to be not supported
   */
  private boolean isSupported(String property) {
    String val = tableMetaData.getModelMetaData().getProperties().getProperty(property);
    return val == null ? true : Boolean.valueOf(val);
  }

  /**
   * Sets whether a feature is supported by the backend.
   * @param property the feature
   * @param supported true if supported, false if not supported
   */
  private void setSupported(String property, boolean supported) {
    tableMetaData.getModelMetaData().getProperties().setProperty(property, Boolean.toString(supported));
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy