JDBC Support

All NetCharts applets support the use of the JDBC interface to retrieve parameter definitions or data values from one or more database servers. The JDBC interface is completely platform and server independent, providing a wide range of implementation alternatives. This document decribes the basic operation of the JDBC, how to install the necessary software and how to use the JDBC interface with NetCharts charts.

The following specific issues are addressed in this document:

JDBC Overview

The basic steps needed to perform database processing within the JDBC are as follows:

  • Register a driver
  • Connect to a database server
  • Execute a database statement (e.g., SQL)
  • Process any tabular results returned
  • The JDBC interface works on the "driver" principle in order to provide platform independent operation. That is, all of the database specific processing is performed by specific drivers, which may or may not be produced by the database vendor. At run-time, the user or developer can decide which driver to "register" and therefore which "server" to connect to.

    Connections generally require some sort of login information, such as a username and password, but this varies from one database server to another. Since different database systems require different items, the JDBC defines a "properties" table that can contain an arbitrary number and type of values that are provided to the database server when a connection is made. In that way, the JDBC methods can work with any database server now or in the future.

    Once a connection is made, one or more statements can be executed, which may return zero or more tables of data containing one or more rows each. When tabular results are returned, they can be processed in any manner and in any form (e.g., string, numeric, date/time) required by the client application. Once the results are processed or the current statement is canceled, another statement can be executed on that connection.

    The JDBC is indeed a flexible interface that supports most database application needs.

    JDBC Installation

    JDBC support is built into all NetCharts applets and, as such, no additional installation is required for NetCharts applets themselves. However, as described above, the JDBC requires the use of one or more drivers in order to connect to the database server. Such drivers are sold by a wide range of vendors, including all major database vendors and quite a few 3rd party vendors. Each vendor has their own installation requirements and procedures, including possibly the use of a middleware or proxy server to facilitate communication between the driver and the database server.

    Since the installation procedures vary from product to product, we cannot address them specifically here. However, there are a number of common circumstances to consider.

    JDBC support is provided as an integral part of the JDK 1.1 release from JavaSoft. Therefore, if you are using that version directly or your browser supports that version, then you need only install the driver itself according to the vendors instructions. If so, you can proceed to the next section Driver Installation

    If you are using an older version of the JDK, such as 1.0.2, or an older browser, then you'll need to install the JDBC classes themselves, in addition to the driver classes. The JDBC classes are usually included with the driver distribution for your convenience in the javasql.zip file. Since those classes are part of the java.* foundation classes, they must be installed on the local machine, wherever the browser or appletviewer is located. In both cases, simply place the zip file anywhere in the filesystem and then add that pathname to your CLASSPATH environment variable. (See your browser installation procedures for the details for your specific browser.)

    For example, if your JDK is located in /java and you placed the javasql.zip file in the "lib" subdirectory, then the following CLASSPATH definition would allow the appletviewer to find the necessary JDBC classes:

    CLASSPATH = /java/lib/classes.zip:/java/lib/javasql.zip
    

    When using the Netscape browser, for example, suppose you have stored the standard Netscape files and the javasql.zip in the /netscape directory. In that case, the following CLASSPATH variable should be set prior to executing the browser:

    CLASSPATH = /netscape/java_301:/netscape/javasql.zip
    

    Driver Installation

    Once you have installed the basic JDBC classes, you can install the driver classes according to the driver vendor's instructions. Generally, this involves copying the classes into your java class directory either as individual classes or as a ZIP file. Since you will be using the drivers with NetCharts applets, it may be convenient to place them in the same directory. Since the driver classes use different names than NetCharts classes, there is no risk of overwriting a NetCharts class.

    For example, Sybase distributes their driver class files in both the sybjdbc.zip file and in the "classes" subdirectory of their distribution. When using an older browser, which only supports a single directory name in the CODEBASE attribute of the APPLET tag, it is most convenient to copy the contents of the Sybase "classes" directory into the NetCharts classes directory. That merges both class hierarchies and allows you to use NetCharts classes or Sybase JDBC classes or both, using the same CODEBASE definition. In that case, the NetCharts applet tag would look like the following:

    <applet codebase=/NetCharts/classes
    	code=NFPiechartApp.class
    	width=400 height=400>
    ....
    </applet>
    

    Making A Server Connection

    Once the JDBC classes and driver classes are installed properly, any NetCharts applet is capable of connecting to any database server supported by a JDBC driver. As described above, the actual login information needed to make each connection is database server dependent, and is managed through the use of a set of named "properties". NetCharts provides complete support for such connection properties through the JdbcLogin parameter, which has the following syntax:

    JdbcLogin = ("property1", "value1", "label1", mode1),...;
    	"property" - the name of the database specific property
    	"value"    - the value to be provided for that property
    	"label"    - optional label to display to user
    	mode       - HIDDEN | READONLY | READWRITE | NOECHO | MENU
    

    The JdbcLogin parameter can contain one or more tuples, depending on the needs of the database server.

    The first two attributes define the name and value of each property to be provided when connecting to the database server. Some servers require that a specific set of parameters be defined at all times, such as username and password, with other parameters that are optional. Additionally, NetCharts requires that the "driver" and "server" properties be set, to indicate the desired driver and server to be used, respectively.

    For example, when connecting to a Sybase server, the following JdbcLogin parameter could be used:

    JdbcLogin = 
    	("driver",   "com.sybase.jdbc.SybDriver"),
    	("server",   "jdbc:sybase:Tds:netcharts:3000"),
    	("user",     "fred"),
    	("password", "myfavoritecar");
    

    Note, in this case, all property values are completely defined (ie. hardcoded), providing all of the information needed by both NetCharts and Sybase to establish the connection. The "driver" property specifies the name of the driver class to be used, using the standard JDBC format. Similarly, the "server" property specifies the protocol (Tds), hostname (netcharts) and port number (3000) of the desired server. The "user" and "password" properties are required by the Sybase server. Other database servers may require different properties according to their specific needs.

    After the JdbcLogin parameter has been processed, a connection will be made when the first JDBC expression is found in the parameter stream. If multiple JdbcLogin parameters are specified, interspersed with JDBC commands, then a new connection will be established and the old one will be terminated. This allows both static and dynamic NetCharts applets to access multiple servers to retrieve parameters or data.

    Login Window

    Clearly, it is not always desirable to have the database username and password stored in an HTML file that is accessible by anyone (now that's a understatement!!!). Therefore, NetCharts provides a user-definable login window that is automatically displayed whenever a connection is requested and some of the properties have been left undefined. Specifically, if one or more of the properties in the JdbcLogin parameter are defined to be NULL, then the login window will appear, requiring the user to enter the data.

    The last two attributes in each of the JdbcLogin tuples are used to control the contents and behavior of the fields in the login window. The "label" attribute can be used to specify the label to be displayed for that property field in the window. This allows developers to display a more meaningful label than the name of the property itself. The "mode" attribute defines how the property field should be displayed and how it will behave.

    For example, the following JdbcLogin parameter could be defined when connecting to a Sybase server:

    JdbcLogin =
    	("driver",   "com.sybase.jdbc.SybDriver",, HIDDEN),
    	("server",   "jdbc:sybase:Tds:netcharts:3000", "Server: ", MENU),
    	("user",     "fred", "Username: ",  READWRITE),
    	("password",  NULL, "Password: ",   NOECHO);
    

    Notice, the "password" value is defined to be NULL, which causes the following login window to be displayed:

    Since the "driver" mode is set to HIDDEN, that property is not displayed. The "user" mode is set to READWRITE, which allows the user to modify the initial value of "fred" if necessary. Similarly, the user can input the password value, which is initially not defined, although the actual characters entered will not be echoed. Rather, a star will be displayed for each character. Finally, the "server" mode is set to MENU, which causes a choice list to be displayed for that field, allowing the user to select one of the given choices. Notice, the label attribute of each field is set to control the display labels, except for "driver", which is not displayed anyway.

    If the MENU mode is needed, the JdbcMenu parameter is used to define the entries for all menus, with the following syntax:

    JdbcMenu = ("name1", "label1", "value1"), ...;
    	name  - property name
    	label - label to be included in menu
    	value - value to be sent to server
    

    One or more tuples can be defined for the JdbcMenu parameter, each representing one entry in a given menu. Since multiple menus may be needed for different properties, the "name" attribute defines to which property the menu item applies. The "label" attribute is what is actually shown to the user in the menu, while the "value" attribute is the actual value sent to the server when that menu item is selected by the user.

    For example, in the example above, the following JdbcMenu parameter could be used:

    JdbcMenu =
    	("server", "Admin Server", "jdbc:sybase:Tds:netcharts:3000"),
    	("server", "Sales Server", "jdbc:sybase:Tds:netcharts:4444");
    
    This parameter definition causes a two entry choice menu to be displayed for the "server" field, allowing the user to easily select a database server, without having to know the complex syntax.

    If we wanted to allow the user to select a different user account as well, the following parameters could be used:

    JdbcLogin =
    	("driver",   "com.sybase.jdbc.SybDriver",, HIDDEN),
    	("server",   "jdbc:sybase:Tds:netcharts:3000","Server: ",MENU),
    	("user",     "fred", "Username: ",  MENU),
    	("password",  NULL,  "Password: ",   NOECHO);
    
    JdbcMenu =
    	("server", "Admin Server", "jdbc:sybase:Tds:netcharts:3000"),
    	("server", "Sales Server", "jdbc:sybase:Tds:netcharts:4444"),
            ("user",   "Admin",        "sa"),
            ("user",   "Fred Smith",   "fred");
    
    Note, in this case, the JdbcMenu parameter defines two different menus, one each for the "server" and "user" properties, using the same syntax.

    The exact appearance of the login window can be controlled using the following parameters:

    JdbcTitle = ("title", fontColor, "fontName", fontSize);
    	title     - window title
    	fontColor - title color
    	fontName  - title font
    	fontSize  - title font size
    
    JdbcColor = (labelBG, labelFG, fieldBG, fieldFG);
    	labelBG - label/window background color
    	labelFG - label/window foreground color
    	fieldBG - entry field background color
    	fieldFG - entry field foreground color
    
    JdbcFont = ("labelFont", labelSize, "fieldFont", fieldSize);
    	labelFont - font name for labels
    	labelSize - font size for labels
    	fieldFont - font name for entry fields
    	fieldSize - font size for entry fields
    

    All of these parameters are optional and all of the attributes defined within any of these parameters are optional. If any attribute is not defined, a default value will be used.

    Defining Data Values Using JDBC

    Once a Jdbc connection has been defined using the JdbcLogin parameter, any number of JDBC statements can be executed within a parameter definition script, file or server stream. Since neither NetCharts nor the JDBC restricts the types of statements that can be executed by the server, any statement accepted by the server can be processed through NetCharts. If the statement returns tabular results, NetCharts automatically processes all of the rows and columns returned to determine how to define the current parameter.

    The following syntax is used whenever a JDBC statement is used to define NetCharts data values:

    parameterName = JDBC statement;
    

    The JDBC keyword denotes the beginning of a JDBC statement, which may contain any number and types of characters, but it must end with a semi-colon. The statement may contain any valid statement accepted by the current JDBC server.

    Single Attribute

    For example, the following statement is valid for a Sybase server:

    GraphType = JDBC select "GROUP";
    

    In this case, a trivial select statement is executed that returns the desired GraphType setting. (Any skilled SQL programmer can easily expand such a query into as complex an expression as needed!) Since the GraphType parameter only accepts a single attribute, only a single row and column should be returned. If multiple columns are returned in this case, only the first is used. If multiple rows are returned, each row is processed in turn, resulting in the value from the last row being used for the final setting of GraphType.

    Tuple of Attributes

    In the following example, another trivial select statement is used to define the first four attributes of the Header parameter.

    Header = JDBC select "Param Test", "black", "TimesRoman", 18;
    

    Notice, there is a mixture of string and numeric results, representing various NetCharts attribute types. Regardless of the type of the columns returned, NetCharts will automatically attempt to convert the values to the necessary type defined for each attribute.

    Since the Header parameter is a single tuple parameter, all of the columns returned are used in the order received. That is, the first column defines the first attribute, the second the second, and so on. If too many columns are returned for the given tuple, the remaining columns are ignored. If too few are returned, the remaining tuple attributes are set to their defined default values.

    For single tuple parameters, if multiple rows are returned, each row is processed. That means that the value of the last row will be assigned as the final value of each attribute in the tuple.

    Vector of Attributes

    In the following example, the LineSet1 parameter is defined using a select statement that returns multiple rows, each containing two numeric columns, with the rows sorted by the first column.

    LineSet1 = JDBC	select	 x, y
    		from	 points
    		order by x;
    

    This clearly demonstrates the ease with which data sets can be retrieved using a JDBC statement. Since the LineSet1 parameter accepts a vector of tuple values, all of the rows are used to define different data points in the data set.

    Multiple JDBC Statements

    The JDBC keyword can be used to pass both small and large statements to the JDBC server. Such expressions may contain any number of statements, as expressed in the server's syntax, which may or may not return results. In all cases, if tabular results are returned, they are automatically assigned to the current parameter.

    For example, the following parameter definition can be used to perform various operations within a Sybase server:

    LineSet2 = JDBC
    	create table #mytable (x int, y int)
    
    	insert  #mytable values (50, 20)
    	insert  #mytable values (60, 20)
    	insert  #mytable values (60, 30)
    
    	select  *
    	from    #mytable
    	;
    

    Defining Parameters Using JDBC

    The most common method of using JDBC within NetCharts applets is for the definition of data values within a parameter definition. However, such an approach is not always desirable, depending on the specific application. Furthermore, it may be necessary to execute specific database statements that have nothing to do with a given parameter.

    In such cases, the JdbcQuery directive can be used to execute arbitrary JDBC statements, using the following syntax:

    JdbcQuery = JDBC statement;
    

    This is the easiest way to execute "administrative" statements, such as in the following example for Sybase:

    JdbcQuery = JDBC use mydatabase;
    
    LineSet1  = JDBC select	  x, y
    		 from	  points
    		 order by x;
    

    In this case, the JdbcQuery directive is used to execute the "use mydatabase" command, which instructs the Sybase server to change the current database. Since that command must be executed separately, according to Sybase processing requirements, it is executed in the JdbcQuery statement prior to issuing the query to define LineSet1.

    Any number of JdbcQuery directives can be specified within a parameter script, with each directive executed before any subsequent parameters are processed. That is, the JdbcQuery directives are treated like "parser commands", which are executed during the parameter parsing process and therefore affect all subsequent JDBC parameters. In short, JdbcQuery directives and JDBC statements are processed from top to bottom in a script.

    If the statement(s) executed by JdbcQuery return tabular results, then the results must contain two columns, in which the first column specifies the name of a NetCharts parameter and the second column specifies the desired "definition". The definition should be a valid text string, using the standard parameter syntax for NetCharts parameters.

    For example, the following query can be used to define a set of common parameters for a Pie Chart:

    JdbcQuery = JDBC
    	select	param, defn
    	from	paramTable
    	where	chart = "pie";
    

    assuming that paramTable was defined as follows in the database:

    create table paramTable
    (
    	chart	varchar(16),
    	param	varchar(16),
    	defn	varchar(255)
    )
    
    insert paramTable values ("pie", "Header",    "('Piechart', black)")
    insert paramTable values ("pie", "HeaderBox", "(lightGray, RAISED)")
    
    insert paramTable values ("bar", "Header",    "('Barchart', red)")
    insert paramTable values ("bar", "HeaderBox", "(white, SHADOW, 4)")
    

    This feature allows developers to easily define commonly used parameters in a database table, using the same syntax used in all NetCharts parameter scripts, and then extract those definitions that are needed in a given application using the full power of the database.

    NULL Values

    Certain NetCharts applets support the use of NULL values for specific attributes, such as data points in a LineSet or the color of a bar. In those cases, the NULL value is interpreted according to the specification of the given parameter in the given chart.

    The NULL value can be assigned via a JDBC command, by generating either a NULL database value (as defined in SQL) or by generating the string "NULL". In both cases, the attribute will be assigned a NULL value (as defined in NetCharts) if appropriate for that attribute.

    NetCharts tuple definitions also allow a given attribute to be skipped, such as in the following example:

    Header = ("Piechart",,,16);
    

    In that case, the second and third attributes have been skipped, resulting in the default values being assigned to those attributes.

    When using JDBC statements to specify tuples, there is no equivalent mechanism for skipping an attribute. That is, successive columns are used to define successive tuple attributes, with no jumps. If a NULL value is defined, then it will be stored as the value of that attribute, if allowed.

    For example, the following JDBC statement assigns a NULL color to all piechart slices, which is allowed for that specific attribute:

    Slices = JDBC	select	salary, NULL, name
    		from	employees;
    

    Dynamically Updated Charts

    The JDBC support in NetCharts is 100 percent compatible with the dynamic update feature provided through the NFParamServer parameter. In that case, a Parameter Server is used to dynamically generate NetCharts parameters, interspersed with "Update" commands to update the chart being displayed. Since JDBC support is provided through the same parameter syntax, it can also be generated dynamically by the Parameter Server.

    Here again, once the JDBC connection has been made, any number of JDBC statements can be executed. Furthermore, additional JdbcLogin parameters can be specified to cause a new database connection to be established. In that case, the old connection is automatically closed.

    This integration of features allows developers to either extract the data directly from a database in the Parameter Server and then forward it to the chart, or to simply instruct the chart to pull the data directly from the database server when it needs to be updated. In both cases, the Parameter Server is in complete control of what is updated and when those updates occur.

    See Parameter Server for more details concerning the use of a Parameter Server for dynamic chart updates.

    Embedded Applets/Applications

    One of the easiest methods of controlling a NetCharts applet from within another Java applet or application is through the use of the loadParams() method. (See Parameter for details.) That method accepts any arbitrary String expression that is parsed to determine the desired parameter definitions. Since the JDBC keyword is implemented using the same parameter definitions, it can also be used in conjunction with the loadParams() method for embedded charts.

    Performance Issues

    The JDBC support provided by NetCharts is not intended to completely replace the database programming performed by CGI and Java application programmers using NetCharts applets. Although it is very capable of performing many necessary database chores, it is unreasonable to assume that it can replace the need for custom programming in all situations. Therefore, the JDBC feature can be combined, as needed, with CGI or Java programming techniques to achieved the desired result.

    With regards to performance, however, there are some benefits to be gained by using JDBC statements within NetCharts parameters, as opposed to performing the equivalent database statements in CGI scripts or Java applets/applications, which then generate NetCharts parameters.

    In the case of CGI scripts, the database commands are processed on the Web Server, which may not be capable of sustaining such workloads and then the results need to be translated and output as a collection of NetChart parameters within an HTML file. In some cases, only a few of the parameters are defined using the database (primarily data sets) and the amount of processing performed and code required is wasteful of resources.

    By simply embedding the database commands in NetCharts parameters, as JDBC statements, the chart can automatically connect to the server and retrieve the information as needed. In some cases, that alone can eliminate the need for a CGI script altogether, resulting in a statically defined HTML file with JDBC commands. When the user retrieves that file, the chart will automatically get the needed data. Additionally, since browsers cache HTML files, but not the output of CGI scripts, whenever the user goes "Back" to the file, only a minimal network delay will be seen to check the modification date of the HTML file and to connect to the database. Finally, this capability allows HTML authors to retrieve data directly into a document simply by including a few lines of SQL syntax provided to them by a database programmer, without needing the assistance of a CGI programmer and hard to maintain CGI database scripts.

    When NetCharts are embedded within Java applets or applications, it is also a performance benefit to have the chart retrieve and process the results, as opposed to performing the database functions in the applet and then translating the results into String expressions for the loadParams() method. The time saved converting the results is usually substantial (especially if the String class is used, instead of the StringBuffer class!!!) and can be eliminated for the most part, by allowing the chart to process the results directly. (The NetCharts parameter parser is highly optimized for its intended purpose, including the processing of database results.)

    Trouble-Shooting

    The most common problems encountered when using the JDBC support in NetCharts is usually due to the improper installation of the JDBC driver or the misconfiguration of the login properties. With regard to installation problems, which are inherently dependent on the specific JDBC driver and server being used, we strongly advise you to follow the vendor's installation instructions precisely. Furthermore, before attempting to use JDBC statements within a NetCharts chart, you should make sure that:

  • the JDBC driver works outside of NetCharts,
  • any required middleware/proxy server is running,
  • the databaser server is running, and
  • you know all of the necessary login properties.
  • Once those precautions have been taken, the use of JDBC statements in NetCharts should be straight-forward.

    If you've done everything correctly (as far as you know) and are still having JDBC problems, you can use the DebugSet and DebugClear directives to generate debug information on the Java Console for JDBC operations, using the following syntax:

    DebugSet = JDBC;
    
    DebugClear = JDBC;
    

    The DebugSet command enables the printing of debug messages for all subsequent JDBC statements, including the processing of all Jdbc Parameters, such as JdbcLogin, etc. The debug messages will continue to be printed until the end of the Parameter script or the DebugClear directive is seen.

    For example, the following script defines a simple piechart, enabling debug messages for all JDBC statements:

    DebugSet = JDBC;
    
    JdbcLogin =
    	("driver",   "com.sybase.jdbc.SybDriver"),
    	("server",   "jdbc:sybase:Tds:netcharts:3000"),
    	("user",     "fred"),
    	("password", "howdy");
    
    JdbcQuery = JDBC use master;
    
    Slices    = JDBC select salary, NULL, name from employees;
    
    Header    = ("Piechart", black, "TimesRoman", 16);
    HeaderBox = (white, SHADOW);
    

    Resulting in the following debug output on the Java Console:

    NFJdbc: Set JdbcLoginTuple
    NFJdbc: Set JdbcLoginTuple
    NFJdbc: Set JdbcLoginTuple
    NFJdbc: Set JdbcLoginTuple
    NFJdbc: Set JdbcLogin
    NFJdbc: Parameter = JdbcQuery
    NFJdbc: Registering driver <com.sybase.jdbc.SybDriver>
    NFJdbc: Property driver = <com.sybase.jdbc.SybDriver>
    NFJdbc: Property server = <jdbc:sybase:Tds:netcharts:3000>
    NFJdbc: Property user = <fred>
    NFJdbc: Property password = <howdy>
    NFJdbc: Connecting to server <jdbc:sybase:Tds:netcharts:3000>
    NFJdbc: ++++++++++++++++++++
    NFJdbc: Executing statement:
    	use master
    NFJdbc: Processed 1 statement(s), 0 rows
    NFJdbc: --------------------
    NFJdbc: Parameter = Slices
    NFJdbc: ++++++++++++++++++++
    NFJdbc: Executing statement:
    	select  salary, NULL, name
    	from    employees
    NFJdbc: Row(1) = 10.4|null|fred
    NFJdbc: Row(2) = 78.8|null|sally
    NFJdbc: Row(3) = 25.8|null|jim
    NFJdbc: Row(4) = 89.8|null|bob
    NFJdbc: Row(5) = 17.4|null|gloria
    NFJdbc: Processed 1 statement(s), 5 rows
    NFJdbc: --------------------
    

    In the following example, debug messages are only printed for the data set query itself:

    JdbcLogin =
    	("driver",   "com.sybase.jdbc.SybDriver"),
    	("server",   "jdbc:sybase:Tds:netcharts:3000"),
    	("user",     "fred"),
    	("password", "howdy");
    
    JdbcQuery = JDBC use master;
    
    DebugSet   = JDBC;
    Slices     = JDBC select salary, NULL, name from employees;
    DebugClear = JDBC;
    
    Header    = ("Piechart", black, "TimesRoman", 16);
    HeaderBox = (white, SHADOW);
    

    Resulting in the following debug output on the Java Console:

    NFJdbc: Parameter = Slices
    NFJdbc: ++++++++++++++++++++
    NFJdbc: Executing statement:
    	select  salary, NULL, name
    	from    employees
    NFJdbc: Row(1) = 10.4|null|fred
    NFJdbc: Row(2) = 78.8|null|sally
    NFJdbc: Row(3) = 25.8|null|jim
    NFJdbc: Row(4) = 89.8|null|bob
    NFJdbc: Row(5) = 17.4|null|gloria
    NFJdbc: Processed 1 statement(s), 5 rows
    NFJdbc: --------------------