Skip to content

Adding support of a database vendor

Christophe Fondacci edited this page Feb 9, 2017 · 1 revision

This section will describe a quick guide on how to add the support of a new vendor in neXtep.

== Adding the vendor definition ==

All vendors are defined through an Enum class called DBVendor which you can find in the ''com.neXtep.designer.core'' plugin : com.nextep.designer.core.model.DBVendor

This enumeration defines all database vendors that neXtep supports. In the enum definition, you will have to define a few information such as the default formatter, default client executable name and default port.

Here is what a typical vendor definition looks like :

ORACLE("Oracle", IFormatter.UPPERCASE, "sqlplus", 1521)

== Adding the connectivity == === Adding the new JDBC driver ===

In neXtep, we opted for bundling the JDBC along with the product so that the user is never prompted for a JDBC driver, url pattern, etc.

First, download the vendor's latest production release of their JDBC (if several are available, opt for pure Java). Eclipse provides an easy way to integrate jars as plugin. In the navigator, right clic : ''New… > Others > Plugin from existing jar archive'' and select the driver you downloaded.

Please use the following pattern for JDBC plugins : com.neXtep.designer.jdbc.''vendor''

=== Adding the database connector ===

On top of the JDBC we have an abstraction that allows full abstraction of the connectivity features. This abstraction is done thanks to the ''com.nextep.designer.core.model.IDatabaseConnector'' interface of the core plugin.

To ensure proper organic extension of the neXtep product, you will need to create a new plugin which will represent an extension of neXtep for your specific vendor.

In the neXtep architecture, the connectivity features are generally placed in the ''sqlgen'' plugins along with capturers and generators. You should now create a new Eclipse plugin (''New > Other… > Eclipse plugin project'', default options and '''not contributing to UI''') named on the following pattern : com.neXtep.designer.sqlgen.''vendor''

Now create a new package where you will put your new connector : com.nextep.designer.sqlgen.''vendor''.impl

Create a new class implementing IDatabaseConnector and extending AbstractDatabaseConnector which we will use as a base foundation. Implement the various methods depending on your JDBC's specificities.

Here is an example of the DB2 connector class :

public final class DB2DatabaseConnector extends AbstractDatabaseConnector {

	private static final Log LOGGER = LogFactory.getLog(DB2DatabaseConnector.class);
	private static final String DB2_JDBC_DRIVER_CLASSNAME = "com.ibm.db2.jcc.DB2Driver"; //$NON-NLS-1$

	public DB2DatabaseConnector() {
		super();
	}

	@Override
	public Connection connect() throws SQLException {
		String connURL = getConnectionURL();
		LOGGER.info("Connecting to DB2 database from URL [" + connURL + "]..."); //$NON-NLS-2$
		try {
			return driver.connect(connURL, getConnectionInfo());
		} catch (SQLException sqle) {
			throw new ErrorException("Unable to connect to the DB2 database", sqle);
		}
	}

	@Override
	public String getConnectionURL() {
		return "jdbc:db2://" + getHost() + ":" + getPort() + "/" + getSid(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	@Override
	public String getJDBCDriverClassName() {
		return DB2_JDBC_DRIVER_CLASSNAME;
	}

	@Override
	public Collection showErrors(String objName) {
		// FIXME [BGA]: Check how to fetch errors in DB2
		return Collections.emptyList();
	}

}

=== Registering the database connector ===

Now that you've built your connector, it is time to register it. We do this through eclipse's extension mechanism. Open the ''plugin.xml'' file at the root of your sqlgen.''vendor'' plugin project. In the editor, go in the ''Extensions'' tab and clic on 'Add…'. Select ''com.neXtep.designer.core.dbConnector''. The definition consists in 2 information :

  • The vendor code (= the code of the enum you defined earlier)
  • The connector class you have just created

Save the file and it's done!

== First validation ==

At this step, neXtep should start to work with your vendor with all default features active. Launch the neXtep product in debug mode (don't forget to edit your debug configuration in order to add your new JDBC and sqlgen plugin in the 'Plug-ins' tab of the debug configuration).

We advise you to start to validate the vendor on a repository that you create for another vendor. It will be easier to validate that everything work before trying to deploy a repository on the new vendor.

Start neXtep designer and try to create a new workspace from an existing database in the workspace selection dialog. You should now see your new vendor in the connection's dialog vendor combo. Select all the information and clic ''Test connection''. If this works, it means that your IDatabaseConnector works fine ! If it is not, analyze the logs and fix problems in your connector.

You should be able to :

  • Import an existing database for the new vendor you added (only basic objects like tables, columns, indexes, FK, primary and unique keys)
  • Synchronize the repository with any database (same scope)
  • Generate SQL from version information or from synchronization : note that the syntax will be ANSI 92 and many features like column alteration, rename, etc will not be supported

If your new vendor supports ANSI92 SQL you should then be able to deploy a neXtep repository on it.

== Implementing your vendor-specific features ==

If your validation was successful, you can see that nextep has a flexible architecture which allows it to automatically default most of the intern mechanisms. Now you will see that everything is extendable in order to allow you to implement the specificities of your vendor step by step by extending default mechanisms. We will now see the elements you should customize for your vendor.

=== Adding a parser ===

The first specific implementation you will need to provide for proper integration is a parser definition which will provide the database's reserved keywords, command tags, and some other information used by the editors and the generators. A parser is materialized by the interface : ''com.nextep.designer.sqlgen.model.IParser' :

  • The procedure is exactly the same as what you did for the database connector implementation : ** Create a specific parser implementation ** Declare it through the extension point ''com.neXtep.designer.sqlgen.sqlParser''

=== Adding a datatype provider ===

The datatype provider is the entity defining the types allowed by your vendor. In addition, it also provide information about which types are numeric, which are dates, which are strings, which one could be sized, etc. Again, same procedure to define it through the ''com.nextep.designer.dbgm.datatypeProvider'' extension point.

=== Adding a vendor-specific generator ===

With the configuration you setup, you are working using the default implementations of almost everything : ANSI generators, JDBC capturers, default mergers. You may want to start taking advantage of your new vendor's SQL dialect to allow more SQL operations. Unfortunately, we don't have time to document the whole procedure here so we will provide some hints of how you can do some customization :

  • Start by looking at the ISQLGenerator interface, it allows all kind of SQL generation
  • Generators are typed by elements (tables, views, columns, indexes, etc.), so start by looking at the generation you want to work on and look at what it does, how it does it, and what it does not. Generally the default generators will be called ''TableGenerator'', ''IndexGenerator'', ''ColumnGenerator'' while specific generators are called ''OracleTableGenerator'', or ''MySqlIndexGenerator''.
  • Note that extensions may or may not exist for all vendors or for all element types. You can choose to only provide a generator for columns so that all default generators will be used except when it needs to generate the SQL of a column.
  • Generators are registered through the extension point ''com.neXtep.designer.sqlgen.sqlGenerator''. In the extension you define the type id, the vendor restriction and the implementation of the ISQLGenerator.
  • Look at how this has been done to provide specific generators for DB2, Oracle, or Mysql for example. You'll have plenty of examples.

=== Adding a vendor-specific capturer ===

As you will notice, by default neXtep will not retrieve all objects of your database schema, only the information it could access through JDBC. If you want to be able to capture more information from the database, you will need to define a specific capturer for your vendor.

The interface you need to provide is a ICapturer which is the way to provide objects from a database connection to the environment. Look at the implementation of this class for other vendors (except Oracle which has not fully been refactored yet). Compose this capturer with the JDBCCapturer and specialize what you need.

Once you are done, you will be able to register your new capturer for your vendor through the extension point ''com.neXtep.designer.sqlgen.sqlCapturer''