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:
The basic steps needed to perform database processing within the JDBC are as follows:
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 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:
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:
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:
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:
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:
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.
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:
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:
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:
If we wanted to allow the user to select a different user account
as well, the following parameters could be used:
The exact appearance of the login window can be controlled using the
following parameters:
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.
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:
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.
For example, the following statement is valid for a Sybase server:
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.
In the following example, another trivial select statement is used
to define the first four attributes of the Header parameter.
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.
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.
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.
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:
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:
This is the easiest way to execute "administrative" statements,
such as in the following example for Sybase:
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:
assuming that paramTable was defined as
follows in the database:
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.
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:
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:
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.
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.
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.)
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:
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:
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:
Resulting in the following debug output on the Java Console:
In the following example, debug messages are only printed for the data
set query itself:
Resulting in the following debug output on the Java Console:
JDBC Installation
CLASSPATH = /java/lib/classes.zip:/java/lib/javasql.zip
CLASSPATH = /netscape/java_301:/netscape/javasql.zip
Driver Installation
<applet codebase=/NetCharts/classes
code=NFPiechartApp.class
width=400 height=400>
....
</applet>
Making A Server Connection
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
JdbcLogin =
("driver", "com.sybase.jdbc.SybDriver"),
("server", "jdbc:sybase:Tds:netcharts:3000"),
("user", "fred"),
("password", "myfavoritecar");
Login Window
JdbcLogin =
("driver", "com.sybase.jdbc.SybDriver",, HIDDEN),
("server", "jdbc:sybase:Tds:netcharts:3000", "Server: ", MENU),
("user", "fred", "Username: ", READWRITE),
("password", NULL, "Password: ", NOECHO);
JdbcMenu = ("name1", "label1", "value1"), ...;
name - property name
label - label to be included in menu
value - value to be sent to server
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.
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.
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
Defining Data Values Using JDBC
parameterName = JDBC statement;
Single Attribute
GraphType = JDBC select "GROUP";
Tuple of Attributes
Header = JDBC select "Param Test", "black", "TimesRoman", 18;
Vector of Attributes
LineSet1 = JDBC select x, y
from points
order by x;
Multiple JDBC Statements
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
JdbcQuery = JDBC statement;
JdbcQuery = JDBC use mydatabase;
LineSet1 = JDBC select x, y
from points
order by x;
JdbcQuery = JDBC
select param, defn
from paramTable
where chart = "pie";
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)")
NULL Values
Header = ("Piechart",,,16);
Slices = JDBC select salary, NULL, name
from employees;
Dynamically Updated Charts
Embedded Applets/Applications
Performance Issues
Trouble-Shooting
DebugSet = JDBC;
DebugClear = JDBC;
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);
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: --------------------
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);
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: --------------------