blob: f81417102e6cf06742c7c7cf7240dcbca4a19d9f [file] [log] [blame]
/*
* Copyright (c) 2008-2015 Eike Stepper (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.net4j.internal.db.ddl;
import org.eclipse.net4j.db.DBType;
import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBSchemaElement;
import org.eclipse.net4j.db.ddl.IDBSchemaVisitor;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.spi.db.ddl.InternalDBField;
import org.eclipse.net4j.spi.db.ddl.InternalDBSchema;
import org.eclipse.net4j.spi.db.ddl.InternalDBTable;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
/**
* @author Eike Stepper
*/
public class DBField extends DBSchemaElement implements InternalDBField
{
public static final int DEFAULT_BOOLEAN_PRECISION = 1;
public static final int DEFAULT_INTEGER_PRECISION = 10;
public static final int DEFAULT_DECIMAL_PRECISION = 5;
public static final int DEFAULT_PRECISION = 0;
public static final int DEFAULT_SCALE = 0;
public static final int DEFAULT_CHAR_LENGTH = 1;
public static final int DEFAULT_VARCHAR_LENGTH = 255;
private static final ThreadLocal<Boolean> TRACK_CONSTRUCTION = new InheritableThreadLocal<Boolean>()
{
@Override
protected Boolean initialValue()
{
return false;
}
};
private static final long serialVersionUID = 1L;
private IDBTable table;
private DBType type;
private int precision;
private int scale;
private boolean notNull;
private int position;
/**
* Tracks the construction stack trace to provide better debug infos in IDBTable.addIndex().
*/
private transient Exception constructionStackTrace;
public DBField(IDBTable table, String name, DBType type, int precision, int scale, boolean notNull, int position)
{
super(name);
this.table = table;
this.type = type;
this.precision = precision;
this.scale = scale;
this.notNull = notNull;
this.position = position;
if (TRACK_CONSTRUCTION.get() == Boolean.TRUE)
{
try
{
throw new Exception("The field " + this + " has been constructed here:");
}
catch (Exception ex)
{
constructionStackTrace = ex;
}
}
}
/**
* Constructor for deserialization.
*/
protected DBField()
{
}
@Override
public IDBField getWrapper()
{
return (IDBField)super.getWrapper();
}
public SchemaElementType getSchemaElementType()
{
return SchemaElementType.FIELD;
}
public IDBSchema getSchema()
{
return table.getSchema();
}
public IDBTable getTable()
{
return table;
}
public IDBTable getParent()
{
return getTable();
}
public DBType getType()
{
return type;
}
public void setType(DBType type)
{
assertUnlocked();
this.type = type;
}
public int getPrecision()
{
if (precision == DEFAULT)
{
switch (type)
{
case BOOLEAN:
return DEFAULT_BOOLEAN_PRECISION;
case INTEGER:
return DEFAULT_INTEGER_PRECISION;
case CHAR:
return DEFAULT_CHAR_LENGTH;
case VARCHAR:
case VARBINARY:
return DEFAULT_VARCHAR_LENGTH;
case DECIMAL:
case NUMERIC:
return DEFAULT_DECIMAL_PRECISION;
default:
return DEFAULT_PRECISION;
}
}
return precision;
}
public void setPrecision(int precision)
{
assertUnlocked();
this.precision = precision;
}
public int getScale()
{
if (scale == DEFAULT)
{
return DEFAULT_SCALE;
}
return scale;
}
public void setScale(int scale)
{
assertUnlocked();
this.scale = scale;
}
public boolean isNotNull()
{
return notNull;
}
public void setNotNull(boolean notNull)
{
if (DBIndex.FIX_NULLABLE_INDEX_COLUMNS.get() != Boolean.TRUE)
{
assertUnlocked();
}
this.notNull = notNull;
}
public int getPosition()
{
return position;
}
public void setPosition(int position)
{
assertUnlocked();
this.position = position;
}
public String getFullName()
{
return table.getName() + "." + getName(); //$NON-NLS-1$
}
public void remove()
{
((InternalDBTable)table).removeField(this);
}
public String formatPrecision()
{
int precision = getPrecision();
if (precision > 0)
{
return "(" + precision + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
return ""; //$NON-NLS-1$
}
public String formatPrecisionAndScale()
{
if (scale == DEFAULT)
{
return "(" + getPrecision() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
return "(" + getPrecision() + ", " + getScale() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public Exception getConstructionStackTrace()
{
return constructionStackTrace;
}
@Override
protected void collectElements(List<IDBSchemaElement> elements)
{
// Do nothing
}
@Override
protected void doAccept(IDBSchemaVisitor visitor)
{
visitor.visit(this);
}
@Override
protected void dumpAdditionalProperties(Writer writer) throws IOException
{
writer.append(", type=");
writer.append(getType().toString());
writer.append(", precision=");
writer.append(String.valueOf(getPrecision()));
writer.append(", scale=");
writer.append(String.valueOf(getScale()));
writer.append(", notNull=");
writer.append(String.valueOf(isNotNull()));
}
private void assertUnlocked()
{
((InternalDBSchema)table.getSchema()).assertUnlocked();
}
public static void trackConstruction(boolean on)
{
if (on)
{
TRACK_CONSTRUCTION.set(true);
}
else
{
TRACK_CONSTRUCTION.remove();
}
}
public static boolean isTrackConstruction()
{
return TRACK_CONSTRUCTION.get();
}
}