/**
* Objective Database Abstraction Layer (ODAL)
* Copyright (c) 2004, The ODAL Development Group
* All rights reserved.
* For definition of the ODAL Development Group please refer to LICENCE.txt file
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package com.completex.objective.components.persistency.meta.impl.oracle;
import com.completex.objective.components.log.Log;
import com.completex.objective.components.log.adapter.StdErrorLogAdapter;
import com.completex.objective.components.persistency.UserDefinedTypeMetaColumn;
import com.completex.objective.components.persistency.UserDefinedTypeMetaModel;
import com.completex.objective.components.persistency.UserDefinedTypeMetaTable;
import com.completex.objective.components.persistency.meta.impl.UdtBaseModelLoaderPlugin;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
/**
* @author Gennady Krizhevsky
*/
public class OracleUdtDatabaseModelLoaderPlugin extends UdtBaseModelLoaderPlugin {
private Log logger = StdErrorLogAdapter.newLogInstance();
private Connection connection;
public OracleUdtDatabaseModelLoaderPlugin() {
}
public OracleUdtDatabaseModelLoaderPlugin(String externalFileName, String internalFileName, String outDir, boolean useDatabase) {
super(externalFileName, internalFileName, outDir, useDatabase);
if (internalFileModelLoaderPlugin == null && !useDatabase) {
throw new RuntimeException("Cannot find internal plugin descriptor file by path " + internalDescPath
+ " while useDatabase = false");
}
}
public void setConnection(Connection connection) {
this.connection = connection;
}
public boolean needsConnection() {
return true;
}
public UserDefinedTypeMetaModel load() throws SQLException {
return load(null);
}
protected UserDefinedTypeMetaModel loadModelFromDb(UserDefinedTypeMetaModel modelPar) throws SQLException {
UserDefinedTypeMetaModel userDefinedTypeMetaModel = loadUserTypes(modelPar);
userDefinedTypeMetaModel = loadObjectTypes(userDefinedTypeMetaModel);
userDefinedTypeMetaModel = loadDependency(userDefinedTypeMetaModel);
userDefinedTypeMetaModel = loadTypeAttributes(userDefinedTypeMetaModel);
userDefinedTypeMetaModel = establishTypeHierarchy(userDefinedTypeMetaModel);
return userDefinedTypeMetaModel;
}
private UserDefinedTypeMetaModel establishTypeHierarchy(UserDefinedTypeMetaModel model) {
for (Iterator it = model.typeTableNameIterator(); it.hasNext();) {
String typeName = (String) it.next();
UserDefinedTypeMetaTable table = model.getTypeTable(typeName);
//
// Find if this table has super type
//
String superType = table.getSuperTypeName();
if (superType != null) {
UserDefinedTypeMetaTable superTable = model.getTypeTable(superType);
for (int i = 0; i < superTable.size(); i++) {
UserDefinedTypeMetaColumn superColumn = superTable.getColumn(i);
//
// Find out if this column is present in current (child) table:
//
UserDefinedTypeMetaColumn column = table.getColumn(superColumn.getColumnName());
if (column != null) {
column.setExistInSuperType(true);
}
}
}
}
return model;
}
private UserDefinedTypeMetaModel loadUserTypes(UserDefinedTypeMetaModel model) throws SQLException {
validateConnection();
if (model == null) {
model = new UserDefinedTypeMetaModel();
}
String sqlTypes = "SELECT a.type_name, a.typecode, \n" +
" a.supertype_owner, a.supertype_name,\n" +
" a.typeid\n" +
" FROM sys.user_types a";
Statement statement = null;
ResultSet rsTypes = null;
try {
statement = connection.createStatement();
rsTypes = statement.executeQuery(sqlTypes);
while (rsTypes.next()) {
String type_name = rsTypes.getString("type_name");
String typecode = rsTypes.getString("typecode");
String supertype_owner = rsTypes.getString("supertype_owner");
String supertype_name = rsTypes.getString("supertype_name");
String typeid = rsTypes.getString("typeid");
UserDefinedTypeMetaTable userDefinedTypeInfo = model.getTypeTable(type_name);
if (userDefinedTypeInfo == null) {
userDefinedTypeInfo = new UserDefinedTypeMetaTable();
}
userDefinedTypeInfo.setName(type_name);
userDefinedTypeInfo.setTypeCode(typecode);
userDefinedTypeInfo.setTypeId(typeid);
userDefinedTypeInfo.setSuperTypeName(supertype_name);
userDefinedTypeInfo.setSuperTypeOwner(supertype_owner);
userDefinedTypeInfo.setCollection("COLLECTION".equals(typecode));
model.addColumn(type_name, userDefinedTypeInfo);
}
return model;
} finally {
close(rsTypes, statement);
}
}
private UserDefinedTypeMetaModel loadObjectTypes(UserDefinedTypeMetaModel model) throws SQLException {
validateConnection();
String sqlTypes = "SELECT a.object_name, a.subobject_name, a.object_id, a.data_object_id,\n" +
" a.object_type, a.created, a.last_ddl_time, a.timestamp, a.status,\n" +
" a.temporary, a.generated, a.secondary\n" +
" FROM sys.user_objects a" +
" where temporary = 'N' and generated = 'N' and object_type = 'TYPE' ";
Statement statement = null;
ResultSet rsTypes = null;
try {
statement = connection.createStatement();
rsTypes = statement.executeQuery(sqlTypes);
while (rsTypes.next()) {
String type_name = rsTypes.getString("object_name");
String object_id = rsTypes.getString("object_id");
if (object_id == null) {
throw new RuntimeException("object_id == null for type_name " + type_name);
}
UserDefinedTypeMetaTable userDefinedTypeInfo = model.getTypeTable(type_name);
if (userDefinedTypeInfo == null) {
throw new RuntimeException("Cannot find UserDefinedTypeMetaTable for type " + type_name);
}
userDefinedTypeInfo.setName(type_name);
userDefinedTypeInfo.setObjectId(object_id);
}
return model;
} finally {
close(rsTypes, statement);
}
}
private UserDefinedTypeMetaModel loadDependency(UserDefinedTypeMetaModel model) throws SQLException {
validateConnection();
String sqlTypes = "SELECT a.object_id, a.referenced_object_id\n" +
" FROM sys.public_dependency a\n" +
" where object_id = ?";
String terminatorId = null;
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sqlTypes);
for (Iterator it = model.typeTableNameIterator(); it.hasNext();) {
ResultSet rs;
String key = (String) it.next();
UserDefinedTypeMetaTable userDefinedTypeInfo = model.getTypeTable(key);
String objectId = userDefinedTypeInfo.getObjectId();
statement.setString(1, objectId);
rs = statement.executeQuery();
while (rs.next()) {
String referenced_object_id = rs.getString("referenced_object_id");
boolean isTeminator = !model.containsObjectId(referenced_object_id);
if (isTeminator) {
if (terminatorId != null && !terminatorId.equals(referenced_object_id)) {
throw new RuntimeException("Diff terminator found: " + terminatorId + " vs " + referenced_object_id);
}
terminatorId = referenced_object_id;
} else {
userDefinedTypeInfo.addDependsOnId(referenced_object_id);
if (userDefinedTypeInfo.isCollection()) {
userDefinedTypeInfo.setCollectionOfObjectId(referenced_object_id);
UserDefinedTypeMetaTable dependsOnUserTypeInfo = model.getColumnById(referenced_object_id);
userDefinedTypeInfo.setCollectionOfName(dependsOnUserTypeInfo.getName());
}
}
}
close(rs, null);
}
return model;
} finally {
close(null, statement);
}
}
/**
*
*/
private UserDefinedTypeMetaModel loadTypeAttributes(UserDefinedTypeMetaModel model) throws SQLException {
validateConnection();
String sqlTypes = "SELECT a.type_name, a.attr_name, a.attr_type_mod, a.attr_type_owner,\n" +
" a.attr_type_name, a.length, a.precision, a.scale,\n" +
" a.character_set_name, a.attr_no, a.inherited\n" +
" FROM sys.user_type_attrs a " +
" where type_name = ? order by attr_no";
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sqlTypes);
for (Iterator it = model.typeTableNameIterator(); it.hasNext();) {
String typeName = (String) it.next();
UserDefinedTypeMetaTable typeMetaTable = model.getTypeTable(typeName);
//
// iterarate through type attrs (columns) :
//
ResultSet rs;
statement.setString(1, typeName);
rs = statement.executeQuery();
int index = 0;
while (rs.next()) {
UserDefinedTypeMetaColumn metaColumn = new UserDefinedTypeMetaColumn();
String attr_name = rs.getString("attr_name");
String attr_type_name = rs.getString("attr_type_name");
int length = rs.getInt("length");
int precision = rs.getInt("precision");
int scale = rs.getInt("scale");
metaColumn.setColumnIndex(index);
metaColumn.setColumnAlias(attr_name);
metaColumn.setColumnName(attr_name);
metaColumn.setTypeName(attr_type_name);
int size = Math.max(length, precision);
metaColumn.setColumnSize(size);
metaColumn.setDecimalDigits(scale);
metaColumn.setJdbcType(javaToMetaType.jdbcTypeByDatabaseOne(attr_type_name));
metaColumn.setType(javaToMetaType.dataTypeByDatabaseOne(attr_type_name, scale, size, false));
typeMetaTable.addColumn(metaColumn);
index++;
}
close(rs, null);
}
return model;
} finally {
close(null, statement);
}
}
private void validateConnection() {
if (connection == null) {
throw new NullPointerException("Connection not set");
}
}
private void close(ResultSet rsTypes, Statement statement) {
if (rsTypes != null) {
try {
rsTypes.close();
} catch (SQLException e) {
error("Cannot close ResultSet", e);
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
error("Cannot close statement", e);
}
}
}
private void error(String s, Exception e) {
logger.error(s, e);
}
}
|