/*
* Copyright (c) 2013-2015 Josef Hardi <josef.hardi@gmail.com>
*
* Licensed 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.obidea.semantika.mapping.base.sql;
import static java.lang.String.format;
import java.util.ArrayList;
import java.util.List;
import com.obidea.semantika.database.base.IColumn;
import com.obidea.semantika.database.base.IContainDatabaseObject;
import com.obidea.semantika.database.sql.base.ISqlColumn;
import com.obidea.semantika.database.sql.base.ISqlExpressionVisitor;
import com.obidea.semantika.datatype.AbstractXmlType;
import com.obidea.semantika.datatype.TypeConversion;
import com.obidea.semantika.datatype.XmlDataTypeProfile;
import com.obidea.semantika.datatype.XmlTypeToSqlType;
import com.obidea.semantika.util.CollectionUtils;
import com.obidea.semantika.util.StringUtils;
public class SqlColumn extends ColumnTerm implements ISqlColumn, IContainDatabaseObject<IColumn>
{
private static final long serialVersionUID = 629451L;
private IColumn mColumn;
private String mSchemaName;
private String mTableName;
private String mColumnName;
private String mViewName = ""; //$NON-NLS-1$
private int mColumnType;
private String[] mNameFragments;
private boolean bTypeOverriden = false;
/**
* Constructs a SQL column variable with input <code>column</code> as its
* meta-information.
*
* @param column
* An instance of database object that stores information about a
* table column.
*/
public SqlColumn(IColumn column)
{
super(column);
mColumn = column;
mSchemaName = column.getSchemaName();
mTableName = column.getTableName();
mColumnName = column.getLocalName();
mColumnType = column.getSqlType();
}
@Override
public IColumn asDatabaseObject()
{
return mColumn;
}
@Override
public String getTableOrigin()
{
return mTableName;
}
@Override
public void setViewName(String viewName)
{
if (!StringUtils.isEmpty(viewName)) {
mViewName = viewName;
mNameFragments = null; // notify to update name fragments
notifyVariableNameChanged(createName(getNameFragments()));
}
}
@Override
public String getViewName()
{
return mViewName;
}
public boolean hasViewName()
{
return StringUtils.isEmpty(mViewName) ? false : true;
}
@Override
public String getColumnName()
{
return mColumnName;
}
@Override
public int getColumnType()
{
return mColumnType;
}
@Override
public String[] getNameFragments()
{
if (mNameFragments == null) {
List<String> fragments = new ArrayList<String>();
if (!StringUtils.isEmpty(mViewName)) {
fragments.add(mViewName);
fragments.add(getColumnName());
}
else {
if (!StringUtils.isEmpty(mSchemaName)) {
fragments.add(mSchemaName);
}
if (!StringUtils.isEmpty(mTableName)) {
fragments.add(mTableName);
}
fragments.add(getColumnName());
}
mNameFragments = CollectionUtils.toArray(fragments, String.class);
}
return mNameFragments;
}
@Override
public void overrideDatatype(String datatype)
{
checkTypeConversion(getDatatype(), datatype);
notifyVariableTypeChanged(datatype);
notifyColumnTypeChanged(datatype);
}
private void checkTypeConversion(String oldDatatype, String newDatatype)
{
AbstractXmlType<?> source = XmlDataTypeProfile.getXmlDatatype(oldDatatype);
AbstractXmlType<?> target = XmlDataTypeProfile.getXmlDatatype(newDatatype);
boolean pass = TypeConversion.verify(source, target);
if (!pass) {
throw new IllegalArgumentException(
format("Type conversion error \"%s\" to \"%s\"", source, target)); //$NON-NLS-1$
}
}
private void notifyColumnTypeChanged(String datatype)
{
int oldSqlType = mColumnType;
int newSqlType = XmlTypeToSqlType.get(datatype);
if (newSqlType != oldSqlType) {
mColumnType = newSqlType;
bTypeOverriden = true;
}
}
public boolean isOverriden()
{
return bTypeOverriden;
}
@Override
public boolean isTyped()
{
return true; // SQL column always typed
}
/**
* Returns <code>true</code> if the other SQL column belongs to the same table
* schema in the database.
*/
public boolean isEquivalent(SqlColumn otherColumn)
{
return this.asDatabaseObject().equals(otherColumn.asDatabaseObject());
}
@Override
public void accept(ISqlExpressionVisitor visitor)
{
visitor.visit(this);
}
/*
* Internal use only for debugging.
*/
@Override
public String toString()
{
if (hasViewName()) {
return getViewName() + "." + getColumnName(); //$NON-NLS-1$
}
else {
return getColumnName();
}
}
}