JDO/JPA are APIs for persisting and retrieving objects to/from datastores. They don't provide a way of accessing the schema of the datastore itself (if it has one). In the case of RDBMS it is useful to be able to find out what columns there are in a table, or what data types are supported for example. DataNucleus Access Platform provides an API for this.
The first thing to do is get your hands on the DataNucleus StoreManager and from that the StoreSchemaHandler. You do this as follows
import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; import org.datanucleus.store.StoreManager; import org.datanucleus.store.schema.StoreSchemaHandler; [assumed to have "pmf"] ... StoreManager storeMgr = ((JDOPersistenceManagerFactory)pmf).getStoreManager(); StoreSchemaHandler schemaHandler = storeMgr.getSchemaHandler();
So now we have the StoreSchemaHandler what can we do with it? Well start with the
javadoc for the implementation that is used for RDBMS
So we now want to find out what JDBC/SQL types are supported for our RDBMS. This is simple.
import org.datanucleus.store.rdbms.schema.RDBMSTypesInfo; Connection conn = (Connection)pm.getDataStoreConnection().getNativeConnection(); RDBMSTypesInfo typesInfo = schemaHandler.getSchemaData(conn, "types");
As you can see from the javadocs for RDBMSTypesInfo
we can access the JDBC types information via the "children". They are keyed by
the JDBC type number of the JDBC type (see java.sql.Types).
So we can just iterate it
Iterator jdbcTypesIter = typesInfo.getChildren().values().iterator(); while (jdbcTypesIter.hasNext()) { JDBCTypeInfo jdbcType = (JDBCTypeInfo)jdbcTypesIter.next(); // Each JDBCTypeInfo contains SQLTypeInfo as its children, keyed by SQL name Iterator sqlTypesIter = jdbcType.getChildren().values().iterator(); while (sqlTypesIter.hasNext()) { SQLTypeInfo sqlType = (SQLTypeInfo)sqlTypesIter.next(); ... inspect the SQL type info } }
Here we have a table in the datastore and want to find the columns present. So we do this
import org.datanucleus.store.rdbms.schema.RDBMSTableInfo; Connection conn = (Connection)pm.getDataStoreConnection().getNativeConnection(); RDBMSTableInfo tableInfo = schemaHandler.getSchemaData(conn, "columns", new Object[] {catalogName, schemaName, tableName});
As you can see from the javadocs for RDBMSTableInfo
we can access the columns information via the "children".
Iterator columnsIter = tableInfo.getChildren().iterator(); while (columnsIter.hasNext()) { RDBMSColumnInfo colInfo = (RDBMSColumnInfo)columnsIter.next(); ... }
Here we have a table in the datastore and want to find the indices present. So we do this
import org.datanucleus.store.rdbms.schema.RDBMSTableInfo; Connection conn = (Connection)pm.getDataStoreConnection().getNativeConnection(); RDBMSTableIndexInfo tableInfo = schemaHandler.getSchemaData(conn, "indices", new Object[] {catalogName, schemaName, tableName});
As you can see from the javadocs for RDBMSTableIndexInfo
we can access the index information via the "children".
Iterator indexIter = tableInfo.getChildren().iterator(); while (indexIter.hasNext()) { IndexInfo idxInfo = (IndexInfo)indexIter.next(); ... }
Here we have a table in the datastore and want to find the FKs present. So we do this
import org.datanucleus.store.rdbms.schema.RDBMSTableInfo; Connection conn = (Connection)pm.getDataStoreConnection().getNativeConnection(); RDBMSTableFKInfo tableInfo = schemaHandler.getSchemaData(conn, "foreign-keys", new Object[] {catalogName, schemaName, tableName});
As you can see from the javadocs for RDBMSTableFKInfo
we can access the foreign-key information via the "children".
Iterator fkIter = tableInfo.getChildren().iterator(); while (fkIter.hasNext()) { ForeignKeyInfo fkInfo = (ForeignKeyInfo)fkIter.next(); ... }
Here we have a table in the datastore and want to find the PK present. So we do this
import org.datanucleus.store.rdbms.schema.RDBMSTableInfo; Connection conn = (Connection)pm.getDataStoreConnection().getNativeConnection(); RDBMSTablePKInfo tableInfo = schemaHandler.getSchemaData(conn, "primary-keys", new Object[] {catalogName, schemaName, tableName});
As you can see from the javadocs for RDBMSTablePKInfo
we can access the foreign-key information via the "children".
Iterator pkIter = tableInfo.getChildren().iterator(); while (pkIter.hasNext()) { PrimaryKeyInfo pkInfo = (PrimaryKeyInfo)pkIter.next(); ... }