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

org.apache.torque.engine.database.model.Column Maven / Gradle / Ivy

package org.apache.torque.engine.database.model;

/*
 * 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.
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.torque.engine.EngineException;
import org.apache.torque.engine.platform.Platform;
import org.xml.sax.Attributes;

/**
 * A Class for holding data about a column used in an Application.
 *
 * @author Leon Messerschmidt
 * @author Jason van Zyl
 * @author Jon S. Stevens
 * @author Daniel Rall
 * @author Martin Poeschl
 * @author 
	 * TODO: Handle delimited column names that have non-Java identifier characters in them.
	 *
	 * @return The name to use in defining the Peer class column variable.
	 */
	public String getPeerJavaName() {
		String peerName = name.toUpperCase();
		if (peerName.equals("TABLE_NAME") || peerName.equals("DATABASE_NAME")) {
			peerName = "_" + peerName;
		}
		return peerName;
	}

	/**
	 * Set the name to use in Java sources.
	 */
	public void setJavaName(String javaName) {
		this.javaName = javaName;
	}

	/**
	 * Returns whether the type in the java object should be an object or primitive.
	 */
	public String getJavaType() {
		return javaType;
	}

	/**
	 * Get the location of this column within the table (one-based).
	 *
	 * @return value of position.
	 */
	public int getPosition() {
		return position;
	}

	/**
	 * Get the location of this column within the table (one-based).
	 *
	 * @param v
	 *            Value to assign to position.
	 */
	public void setPosition(int v) {
		this.position = v;
	}

	/**
	 * Set the parent Table of the column
	 */
	public void setTable(Table parent) {
		parentTable = parent;
	}

	/**
	 * Get the parent Table of the column
	 */
	public Table getTable() {
		return parentTable;
	}

	/**
	 * Returns the Name of the table the column is in
	 */
	public String getTableName() {
		return parentTable.getName();
	}

	/**
	 * A utility function to create a new column from attrib and add it to this table.
	 */
	public Inheritance addInheritance(Attributes attrib) {
		Inheritance inh = new Inheritance();
		inh.loadFromXML(attrib);
		addInheritance(inh);

		return inh;
	}

	/**
	 * Adds a new inheritance definition to the inheritance list and set the parent column of the inheritance to the current column
	 */
	public void addInheritance(Inheritance inh) {
		inh.setColumn(this);
		if (inheritanceList == null) {
			inheritanceList = new ArrayList();
			isEnumeratedClasses = true;
		}
		inheritanceList.add(inh);
	}

	/**
	 * Get the inheritance definitions.
	 */
	public List getChildren() {
		return inheritanceList;
	}

	/**
	 * Determine if this column is a normal property or specifies a the classes that are represented in the table containing this column.
	 */
	public boolean isInheritance() {
		return isInheritance;
	}

	/**
	 * Determine if possible classes have been enumerated in the xml file.
	 */
	public boolean isEnumeratedClasses() {
		return isEnumeratedClasses;
	}

	/**
	 * Return the isNotNull property of the column
	 */
	public boolean isNotNull() {
		return isNotNull;
	}

	/**
	 * Set the isNotNull property of the column
	 */
	public void setNotNull(boolean status) {
		isNotNull = status;
	}

	/**
	 * Return NOT NULL String for this column
	 *
	 * @return "NOT NULL" if null values are not allowed or an empty String.
	 */
	public String getNotNullString() {
		return getTable().getDatabase().getPlatform().getNullString(this.isNotNull());
	}

	/**
	 * Return the isProtected property of the column
	 */
	public boolean isProtected() {
		return isProtected;
	}

	/**
	 * Set the isProtected property of the Column
	 */
	public void setProtected(boolean prot) {
		isProtected = prot;
	}

	/**
	 * Set if the column is a primary key or not
	 */
	public void setPrimaryKey(boolean pk) {
		isPrimaryKey = pk;
	}

	/**
	 * Return true if the column is a primary key
	 */
	public boolean isPrimaryKey() {
		return isPrimaryKey;
	}

	/**
	 * Set true if the column is UNIQUE
	 */
	public void setUnique(boolean u) {
		isUnique = u;
	}

	/**
	 * Get the UNIQUE property
	 */
	public boolean isUnique() {
		return isUnique;
	}

	/**
	 * Return true if the column requires a transaction in Postgres
	 */
	public boolean requiresTransactionInPostgres() {
		return needsTransactionInPostgres;
	}

	/**
	 * Utility method to determine if this column is a foreign key.
	 */
	public boolean isForeignKey() {
		return (getForeignKey() != null);
	}

	/**
	 * Determine if this column is a foreign key that refers to the same table as another foreign key column in this table.
	 */
	public boolean isMultipleFK() {
		ForeignKey fk = getForeignKey();
		if (fk != null) {
			Iterator fks = parentTable.getForeignKeys().iterator();
			while (fks.hasNext()) {
				ForeignKey key = (ForeignKey) fks.next();
				if (key.getForeignTableName().equals(fk.getForeignTableName()) && !key.getLocalColumns().contains(this.name)) {
					return true;
				}
			}
		}

		// No multiple foreign keys.
		return false;
	}

	/**
	 * get the foreign key object for this column if it is a foreign key or part of a foreign key
	 */
	public ForeignKey getForeignKey() {
		return parentTable.getForeignKey(this.name);
	}

	/**
	 * Utility method to get the related table of this column if it is a foreign key or part of a foreign key
	 */
	public String getRelatedTableName() {
		ForeignKey fk = getForeignKey();
		return (fk == null ? null : fk.getForeignTableName());
	}

	/**
	 * Utility method to get the related column of this local column if this column is a foreign key or part of a foreign key.
	 */
	public String getRelatedColumnName() {
		ForeignKey fk = getForeignKey();
		if (fk == null) {
			return null;
		} else {
			return fk.getLocalForeignMapping().get(this.name).toString();
		}
	}

	/**
	 * Adds the foreign key from another table that refers to this column.
	 */
	public void addReferrer(ForeignKey fk) {
		if (referrers == null) {
			referrers = new ArrayList(5);
		}
		referrers.add(fk);
	}

	/**
	 * Get list of references to this column.
	 */
	public List getReferrers() {
		if (referrers == null) {
			referrers = new ArrayList(5);
		}
		return referrers;
	}

	/**
	 * Sets the colunm type
	 */
	public void setType(String torqueType) {
		SchemaType type = SchemaType.getEnum(torqueType);
		if (type == null) {
			log.warn("SchemaType " + torqueType + " does not exist");
			type = Column.DEFAULT_TYPE;
		}
		setType(type);
	}

	/**
	 * Sets the colunm type
	 */
	public void setType(SchemaType torqueType) {
		domain = new Domain(getPlatform().getDomainForSchemaType(torqueType));
		if (torqueType.equals(SchemaType.VARBINARY) || torqueType.equals(SchemaType.BLOB)) {
			needsTransactionInPostgres = true;
		}
	}

	/**
	 * Returns the column jdbc type as an object
	 *
	 * @deprecated the type conversion is handled by the platform package (since torque 3.2)
	 */
	@Deprecated
    public Object getType() {
		return TypeMap.getJdbcType(domain.getType()).getName();
	}

	/**
	 * Returns the column type as given in the schema as an object
	 */
	public Object getTorqueType() {
		return domain.getType().getName();
	}

	/**
	 * Utility method to see if the column is a string
	 *
	 * @deprecated will be removed after the 3.3 release
	 */
	@Deprecated
    public boolean isString() {
		return (domain.getType().getName().indexOf("CHAR") != -1);
	}

	/**
	 * Utility method to return the value as an element to be usable in an SQL insert statement. This is used from the SQL loader task
	 */
	public boolean needEscapedValue() {
		String torqueType = domain.getType().getName();
		return (torqueType != null)
		        && (torqueType.equals("VARCHAR") || torqueType.equals("LONGVARCHAR") || torqueType.equals("DATE") || torqueType.equals("DATETIME")
		                || torqueType.equals("TIMESTAMP") || torqueType.equals("TIME") || torqueType.equals("CHAR") || torqueType.equals("CLOB"));
	}

	/**
	 * String representation of the column. This is an xml representation.
	 *
	 * @return string representation in xml
	 */
	@Override
    public String toString() {
		StringBuffer result = new StringBuffer();
		result.append("    \n");

		return result.toString();
	}

	/**
	 * Returns the size of the column
	 */
	public String getSize() {
		return domain.getSize();
	}

	/**
	 * Set the size of the column
	 */
	public void setSize(String newSize) {
		domain.setSize(newSize);
	}

	/**
	 * Try to determine the precision of the field from the size attribute. If size attribute is an integer number, it will be returned. If
	 * size attribute is of the format "Precision,Scale", then Precision will be returned. If size is null or the size value is not an valid
	 * integer, null is returned.
	 * 

* Note: Unparseable values will be logged as a warning. * * @return The precision portion of the size attribute. */ public String getPrecision() { String size = getSize(); if (size == null) { return size; } int cLoc = size.indexOf(','); if (cLoc > 0) { size = size.substring(0, cLoc); } try { Integer.parseInt(size); } catch (NumberFormatException e) { log.warn("getPrecision(): Size attribute found (" + getSize() + ") was not an integer number, using default of null!"); size = null; } return size; } /** * Try to determine the scale of the field from the scale and size attribute. If scale attribute is an integer number, it will be * returned. If size attribute is of the format "Precision,Scale", then Scale will be returned. If scale and size attributes are null or * the scale value found is not an valid integer, a null value is returned. *

* Note: Unparseable values will be logged as a warning. * * @return The precision portion of the size attribute. */ public String getScale() { String scale = domain.getScale(); // Check for scale on size attribute if no scale attribute if (scale == null) { scale = getSize(); if (scale == null) // No scale or size attribute set. { return scale; } int cLoc = scale.indexOf(','); if (cLoc < 0) // Size did not have "P,S" format { return null; } scale = scale.substring(cLoc + 1); } // Validate that scale string found is integer. try { Integer.parseInt(scale); } catch (NumberFormatException e) { log.warn("getScale(): Scale (or size=\"p,s\") attribute found (" + scale + ") was not an integer number, using default of null."); scale = null; } return scale; } /** * Set the scale of the column */ public void setScale(String newScale) { domain.setScale(newScale); } /** * Return the size and scale in brackets for use in an sql schema. * * @return size and scale or an empty String if there are no values available. */ public String printSize() { return domain.printSize(); } /** * Return a string that will give this column a default value. * * @deprecated */ @Deprecated public String getDefaultSetting() { return domain.getDefaultSetting(); } /** * Set a string that will give this column a default value. */ public void setDefaultValue(String def) { domain.setDefaultValue(def); } /** * Get a string that will give this column a default value. */ public String getDefaultValue() { return domain.getDefaultValue(); } /** * Returns the class name to do input validation */ public String getInputValidator() { return this.inputValidator; } /** * Return auto increment/sequence string for the target database. We need to pass in the props for the target database! */ public boolean isAutoIncrement() { return isAutoIncrement; } /** * Set the auto increment value. Use isAutoIncrement() to find out if it is set or not. */ public void setAutoIncrement(boolean value) { isAutoIncrement = value; } public String getAutoIncrementString() { if (isAutoIncrement() && IDMethod.NATIVE.equals(getTable().getIdMethod())) { return getPlatform().getAutoIncrement(); } return ""; } /** * Set the column type from a string property (normally a string from an sql input file) */ public void setTypeFromString(String typeName, String size) { String tn = typeName.toUpperCase(); setType(tn); if (size != null) { domain.setSize(size); } if (tn.indexOf("CHAR") != -1) { domain.setType(SchemaType.VARCHAR); } else if (tn.indexOf("INT") != -1) { domain.setType(SchemaType.INTEGER); } else if (tn.indexOf("FLOAT") != -1) { domain.setType(SchemaType.FLOAT); } else if (tn.indexOf("DATE") != -1) { domain.setType(SchemaType.DATE); } else if (tn.indexOf("TIME") != -1) { domain.setType(SchemaType.TIMESTAMP); } else if (tn.indexOf("BINARY") != -1) { domain.setType(SchemaType.LONGVARBINARY); } else { domain.setType(SchemaType.VARCHAR); } } /** * Return a string representation of the Java object which corresponds to the JDBC type of this column. Use in the generation of * MapBuilders. */ public String getJavaObject() { return TypeMap.getJavaObject(domain.getType()); } /** * Return a string representation of the primitive java type which corresponds to the JDBC type of this column. * * @return string representation of the primitive java type */ public String getJavaPrimitive() { return TypeMap.getJavaNative(domain.getType()); } /** * Return a string representation of the native java type which corresponds to the JDBC type of this column. Use in the generation of * Base objects. This method is used by torque, so it returns Key types for primaryKey and foreignKey columns * * @return java datatype used by torque */ public String getJavaNative() { String jtype = TypeMap.getJavaNativeObject(domain.getType()); if (isUsePrimitive()) { jtype = TypeMap.getJavaNative(domain.getType()); } return jtype; } /** * Return Village asX() method which corresponds to the JDBC type which represents this column. */ public String getVillageMethod() { String vmethod = TypeMap.getVillageObjectMethod(domain.getType()); if (isUsePrimitive()) { vmethod = TypeMap.getVillageMethod(domain.getType()); } return vmethod; } /** * Return ParameterParser getX() method which corresponds to the JDBC type which represents this column. */ public String getParameterParserMethod() { return TypeMap.getPPMethod(domain.getType()); } /** * Returns true if the column type is boolean in the java object and a numeric (1 or 0) in the db. */ public boolean isBooleanInt() { return TypeMap.isBooleanInt(domain.getType()); } /** * Returns true if the column type is boolean in the java object and a String ("Y" or "N") in the db. */ public boolean isBooleanChar() { return TypeMap.isBooleanChar(domain.getType()); } /** * Returns true if the column type is boolean in the java object and a Bit ("1" or "0") in the db. */ public boolean isBit() { return TypeMap.isBit(domain.getType()); } /** * returns true, if the columns java native type is an boolean, byte, short, int, long, float, double, char */ public boolean isPrimitive() { String t = getJavaNative(); return "boolean".equals(t) || "byte".equals(t) || "short".equals(t) || "int".equals(t) || "long".equals(t) || "float".equals(t) || "double".equals(t) || "char".equals(t); } public boolean isUsePrimitive() { String s = getJavaType(); return (s != null && s.equals("primitive")) || (s == null && !"object".equals(getTable().getDatabase().getDefaultJavaType())); } /** * @return Returns the domain. */ public Domain getDomain() { return domain; } /** * @param domain * The domain to set. */ public void setDomain(Domain domain) { this.domain = domain; } private Platform getPlatform() { try { return getTable().getDatabase().getPlatform(); } catch (Exception ex) { throw new IllegalStateException(ex); } } public String getSqlString() { List resultList = new ArrayList(); resultList.add(getName()); String type = getDomain().getSqlType(); if (getPlatform().hasSize(getDomain().getSqlType())) { type += getDomain().printSize(); } resultList.add(type); String defaultStr = getPlatform().filterInvalidDefaultValues(getDomain().getDefaultValue()); if (StringUtils.isNotEmpty(defaultStr)) { resultList.add("default"); if (TypeMap.isTextType(getDomain().getType()) && !getPlatform().isSpecialDefault(defaultStr)) { // TODO: Properly SQL-escape the text. resultList.add(new StringBuffer().append('\'').append(getDefaultValue()).append('\'')); } else { resultList.add(getDefaultValue()); } } if (getPlatform().createNotNullBeforeAutoincrement()) { if (StringUtils.isNotEmpty(getNotNullString())) { resultList.add(getNotNullString()); } } if (StringUtils.isNotEmpty(getAutoIncrementString())) { resultList.add(getAutoIncrementString()); } if (!getPlatform().createNotNullBeforeAutoincrement()) { if (StringUtils.isNotEmpty(getNotNullString())) { resultList.add(getNotNullString()); } } return StringUtils.join(resultList.iterator(), ' '); } /** * Return the correctGetters property of the column * * @return The currentValue of the correctGetters property. * @since 3.2 */ public boolean isCorrectGetters() { return correctGetters; } /** * Set the correctGetters property of the column. If set to true, the column returns is<xxx> as the getter name which is correct * for the Bean Specs but incompatible to pre-3.2 releases. * * @param correctGetters * The new value of the correctGetters property. * @since 3.2 */ public void setCorrectGetters(boolean correctGetters) { this.correctGetters = correctGetters; } /** * Get the value of the inheritance attribute defined in the schema XML. * * @return Returns the inheritanceType. */ public String getInheritanceType() { return inheritanceType; } /** * Add an XML Specified option key/value pair to this element's option set. * * @param key * the key of the option. * @param value * the value of the option. */ public void addOption(String key, String value) { options.put(key, value); } /** * Get the value that was associated with this key in an XML option element. * * @param key * the key of the option. * @return The value for the key or a null. */ public String getOption(String key) { return (String) options.get(key); } /** * Gets the full ordered hashtable array of items specified by XML option statements under this element. *

* * Note, this is not thread save but since it's only used for generation which is single threaded, there should be minimum danger using * this in Velocity. * * @return An Map of all options. Will not be null but may be empty. */ public Map getOptions() { return options; } public int getJdbcType() { return jdbcType; } public void setJdbcType(int jdbcType) { this.jdbcType = jdbcType; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy