org.datanucleus.store.rdbms.table.ViewImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datanucleus-rdbms Show documentation
Show all versions of datanucleus-rdbms Show documentation
Plugin for DataNucleus providing persistence to RDBMS datastores.
The newest version!
/**********************************************************************
Copyright (c) 2002 Mike Martin and others. All rights reserved.
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.
Contributors:
2004 Andy Jefferson - rewritten to remove many levels of inheritance
...
**********************************************************************/
package org.datanucleus.store.rdbms.table;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.datanucleus.store.rdbms.RDBMSStoreManager;
import org.datanucleus.store.rdbms.exceptions.MissingColumnException;
import org.datanucleus.store.rdbms.exceptions.MissingTableException;
import org.datanucleus.store.rdbms.exceptions.NotAViewException;
import org.datanucleus.store.rdbms.exceptions.PrimaryKeyColumnNotAllowedException;
import org.datanucleus.store.rdbms.exceptions.UnexpectedColumnException;
import org.datanucleus.store.rdbms.identifier.DatastoreIdentifier;
import org.datanucleus.store.rdbms.identifier.IdentifierType;
import org.datanucleus.store.rdbms.schema.RDBMSColumnInfo;
import org.datanucleus.store.rdbms.schema.RDBMSSchemaHandler;
import org.datanucleus.util.Localiser;
import org.datanucleus.util.NucleusLogger;
/**
* Representation of a View in a datastore (RDBMS).
**/
public abstract class ViewImpl extends AbstractTable
{
/**
* Constructor, taking the table identifier.
* @param name The identifier for the table.
* @param storeMgr The Store Manager
*/
public ViewImpl(DatastoreIdentifier name, RDBMSStoreManager storeMgr)
{
super(name, storeMgr);
}
/**
* Method to validate the view in the datastore. Validates the existence of the view, and then the specifications of the Columns.
* @param conn The JDBC Connection
* @param validateColumnStructure Whether to validate down to column structure, or just their existence
* @param autoCreate Whether to update the view to fix errors (not used).
* @param autoCreateErrors Errors found during the auto-create process
* @return Whether the database was modified
* @throws SQLException Thrown when an error occurs in the JDBC calls
*/
@Override
public boolean validate(Connection conn, boolean validateColumnStructure, boolean autoCreate, Collection autoCreateErrors)
throws SQLException
{
assertIsInitialized();
long startTime = System.currentTimeMillis();
if (NucleusLogger.DATASTORE.isDebugEnabled())
{
NucleusLogger.DATASTORE.debug(Localiser.msg("031004",this));
}
// Check existence and validity
RDBMSSchemaHandler handler = (RDBMSSchemaHandler)storeMgr.getSchemaHandler();
String tableType = handler.getTableType(conn, this);
if (tableType == null)
{
throw new MissingTableException(getCatalogName(), getSchemaName(), this.toString());
}
else if (!tableType.equals("VIEW")) // TODO Allow "MATERIALIZED VIEW" that some RDBMS support (e.g PostgreSQL)
{
throw new NotAViewException(this.toString(), tableType);
}
// Validate the column(s)
Map unvalidated = new HashMap<>(columnsByIdentifier);
Iterator i = storeMgr.getColumnInfoForTable(this, conn).iterator();
while (i.hasNext())
{
RDBMSColumnInfo ci = (RDBMSColumnInfo)i.next();
DatastoreIdentifier colIdentifier = storeMgr.getIdentifierFactory().newIdentifier(IdentifierType.COLUMN, ci.getColumnName());
Column col = unvalidated.get(colIdentifier);
if (col == null)
{
if (!hasColumnName(colIdentifier))
{
throw new UnexpectedColumnException(this.toString(), ci.getColumnName(), this.getSchemaName(), this.getCatalogName());
}
// Otherwise it's a duplicate column name in the metadata and we ignore it. Cloudscape is known to do this, although I think that's probably a bug.
}
else
{
if (validateColumnStructure)
{
col.validate(ci);
unvalidated.remove(colIdentifier);
}
else
{
unvalidated.remove(colIdentifier);
}
}
}
if (unvalidated.size() > 0)
{
throw new MissingColumnException(this, unvalidated.values());
}
state = TABLE_STATE_VALIDATED;
if (NucleusLogger.DATASTORE.isDebugEnabled())
{
NucleusLogger.DATASTORE.debug(Localiser.msg("045000", (System.currentTimeMillis() - startTime)));
}
return false;
}
/**
* Internal method to generate the SQL statements for dropping the view.
* @return The List of SQL statements.
*/
protected List getSQLDropStatements()
{
assertIsInitialized();
List stmts = new ArrayList<>();
stmts.add(dba.getDropViewStatement(this));
return stmts;
}
/**
* Method to add a Column to the View.
* @param col The column
*/
protected synchronized void addColumnInternal(Column col)
{
if (col.isPrimaryKey())
{
throw new PrimaryKeyColumnNotAllowedException(this.toString(), col.getIdentifier().toString());
}
super.addColumnInternal(col);
}
}