/*
* 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.database;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Set;
import org.slf4j.Logger;
import com.obidea.semantika.database.base.IForeignKey;
import com.obidea.semantika.database.base.IPrimaryKey;
import com.obidea.semantika.database.base.ITable;
import com.obidea.semantika.database.exception.DataSourceException;
import com.obidea.semantika.database.internal.InternalDatabase;
import com.obidea.semantika.database.sql.dialect.IDialect;
import com.obidea.semantika.util.LogUtils;
/**
* An implementation of JDBC database.
*/
public class JdbcDatabase implements IDatabase
{
private String mDatabaseProduct;
private int mDatabaseMajorVersion;
private int mDatabaseMinorVersion;
private IDialect mDialect;
private InternalDatabase mInternal;
private static final Logger LOG = LogUtils.createLogger("semantika.database"); //$NON-NLS-1$
public JdbcDatabase(final Connection conn) throws DataSourceException
{
try {
DatabaseMetaData metadata = conn.getMetaData();
mDatabaseProduct = metadata.getDatabaseProductName();
mDatabaseMajorVersion = metadata.getDatabaseMajorVersion();
mDatabaseMinorVersion = metadata.getDatabaseMinorVersion();
}
catch (SQLException e) {
LOG.error("Unable to get information about the database"); //$NON-NLS-1$
LOG.error("Detailed cause: {}", e.getMessage()); //$NON-NLS-1$
throw new DataSourceException("Unable to get information about the database", e); //$NON-NLS-1$
}
try {
mInternal = buildInternalDatabase(conn);
}
catch (SQLException e) {
LOG.error("Unable to build the internal structure of database"); //$NON-NLS-1$
LOG.error("Detailed cause: {}", e.getMessage()); //$NON-NLS-1$
throw new DataSourceException("Unable to build the internal structure of database", e); //$NON-NLS-1$
}
}
@Override
public String getDatabaseProduct()
{
return mDatabaseProduct;
}
@Override
public int getDatabaseMajorVersion()
{
return mDatabaseMajorVersion;
}
@Override
public int getDatabaseMinorVersion()
{
return mDatabaseMinorVersion;
}
public void setDialect(IDialect dialect)
{
mDialect = dialect;
}
@Override
public IDialect getDialect()
{
return mDialect;
}
@Override
public IDatabaseMetadata getMetadata()
{
/**
* Implementation of a lazy-built database metadata.
*/
return new IDatabaseMetadata()
{
/**
* Returns the <code>ITable</code> object given the full qualified name.
* If the name already exists, the metadata returns the object from its
* cache, otherwise it contacts the JDBC metadata to retrieve the
* information and create the object.
*/
@Override
public ITable getTable(String fullName)
{
return mInternal.getValue(mInternal.getTableReferences(), fullName);
}
/**
* Returns a set of <code>ITable</code> objects that are stored in the
* metadata cache. Accordingly, the metadata doesn't provide the
* complete information about the tables stored in the database but
* instead it only returns the recognized ones (i.e., from method
* calling <code>getTable(java.lang.String)</code>).
*/
@Override
public Set<ITable> getTables()
{
return mInternal.getAllValues(mInternal.getTableReferences());
}
/**
* Returns a set of <code>IPrimaryKey</code> objects that are stored in
* the metadata cache. Accordingly, the metadata doesn't provide the
* complete information about the primary keys stored in the database
* but instead it only returns the recognized ones (i.e., from method
* calling <code>getTable(java.lang.String)</code>).
*/
@Override
public Set<IPrimaryKey> getPrimaryKeys()
{
return mInternal.getAllValues(mInternal.getPrimaryKeyReferences());
}
/**
* Returns a set of <code>IForeignKey</code> objects that are stored in
* the metadata cache. Accordingly, the metadata doesn't provide the
* complete information about the foreign keys stored in the database
* but instead it only returns the recognized ones (i.e., from method
* calling <code>getTable(java.lang.String)</code>).
*/
@Override
public Set<IForeignKey> getForeignKeys()
{
return mInternal.getAllValues(mInternal.getForeignKeyReferences());
}
};
}
private InternalDatabase buildInternalDatabase(Connection conn) throws SQLException
{
DatabaseMetaData metadata = conn.getMetaData();
return new InternalDatabase(metadata);
}
}