Subject Re: [Firebird-Java] Release notes rev 1
Author David Jencks
Many thanks for doing this. Do you have an html version of this? We
aren't getting a lot of response yet, so maybe we should include pretty
much this with a "beta notice".

I discovered I need to do some refactoring to support non-jboss app
servers, so I would like to get our current version out, do the
refactoring, and release another beta soon.

Thanks
david jencks

On 2002.09.06 17:37:52 -0400 Rick Fincher wrote:
> Hi All,
>
> Below is rev 1 of the release notes for the JCA-JDBC Driver (Jaybird?).
>
> It is very long so please delete all but the pertinent parts when you
> reply,
> otherwise we'll all be getting monster messages with multiple copies of
> this.
>
> I started with the old release notes and stole every other scrap of info
> I
> could find on this driver, and using Java with Firebird/Interbase in
> general. Some of it may be outdated, please say so. I don't
> useJBuilder,
> for example, so I don't have a clue if that info is correct.
>
> I'm also not real sure of the current state of the extra jar files, so
> those
> in the know please check those parts.
>
> Please comment. We need your help to make this a useful document. I
> particularly need help with "Common Errors", "Frequently Asked
> Questions",
> and "Using Multi-Byte Character Sets". A better title for the latter
> might
> be "Character Encoding".
>
> When we decide on a name (Jaybird seems favored right now) I'll replace
> all
> the references to "the driver" with that name. This should help sorting
> references to this driver as opposed to Interclient and others.
>
> If the web site for this driver is up, I'll be happy to maintain a FAQ
> and
> build an HTML page for it.
>
> Please suggest any changes: spelling, grammar, code syntax, new
> sections,
> different section names, etc.
>
> If my tortured prose sets your teeth on edge please feel free to suggest
> alternate language.
>
> Thanks,
>
> Rick
>
>
>
> #####################################################
> #
> # JCA/JDBC Firebird Driver Release Notes
> #
> #####################################################
>
> - Last Updated 09/06/02 -
>
> CONTENTS
>
>
> 1. Introduction
>
> 2. What Is and Is NOT Supported
>
> 3. Where to get the driver
>
> 4. Installing the driver
>
> 5. Connection Pooling
>
> 6. Using the Driver in Java Code
>
> 7. Using the Driver with JBoss
>
> 8. Using the Driver with Tomcat
>
> 9. Using the Driver With JBuilder
>
> 10. Using Blobs
>
> 11. Using Multi-Byte Character sets
>
> 12. Reporting Bugs
>
> 13. Obtaining Sources from SourceForge using CVS
>
> 14. Participating in the Development Project
>
> 15. Where to get help
>
> 16. Joining the Mailing List
>
> 17. Known Bugs
>
> 18. Additional JAR libraries needed to use the driver
>
> 19. Code Examples
>
> 20. Common Errors
>
> 21. Compliance and Performance Information
>
> 22. History
>
> 23. Frequently Asked Questions
>
>
>
> ********************************************************
>
> 1- Introduction
>
> ********************************************************
>
> The firebird team has implemented a pure java driver for firebirdsql.
> This
> driver allows a Java program to
>
> connect to, send queries to, and get results from a Firebird SQL
> Database.
> It is an alternative to the
>
> Interclient JDBC Driver. The open source version of Interclient is not
> actively supported at this time. This
>
> makes the JCA-JDBC Driver the best option for Java development with an
> open
> source driver.
>
> This driver is based on both the new JCA standard for application server
> connections to enterprise information
>
> systems and the well known jdbc standard. The JCA standard specifies an
> architecture in which an application
>
> server can cooperate with a driver so that the application server manages
> transactions, security, and resource
>
> pooling, and the driver supplies only the connection functionality. While
> similar to the JDBC 2 XADataSource
>
> idea, the JCA specification is considerably clearer on the division of
> responsibility between the application
>
> server and driver.
>
> The JCA-JDBC driver has several major advantages over Interclient.
> Because
> it Implements the JCA
>
> specification, it can be used seamlessly with J2EE containers that
> support
> JCA functionality.
>
> It also has a built-in connection pooling capability for use with
> stand-alone programs or J2EE containers that
>
> don't support connection pooling internally. Java programs run much
> faster
> with connection pooling because the
>
> overhead of connection setup and teardown is greatly reduced.
>
> Perhaps the biggest advantage is that Interserver is not needed with this
> driver. Interserver had to be
>
> installed on the Firebird/Interbase server machine for the Interclient
> JDBC
> driver to work. The elimination of
>
> Interserver simplifies the installation of the Firebird database, and
> reduces the load on and maintenance of
>
> the database server system.
>
> The driver implements much of the JDBC Type 4 Driver Specification. More
> information on the JDBC Type 4 Driver
>
> Specification can be found on the net at http://java.sun.com
>
>
>
> ********************************************************
>
> 2- What Is and Is NOT Supported
>
> ********************************************************
>
> The driver complies with the JDBC 2.0 core with some features and methods
> not implemented. Some of the
>
> unimplemented items are required by the specification and some are
> optional.
>
> Implemented features:
>
> Most useful jdbc functionality ("useful" in the opinion of the
> developers).
>
> Complete jca spi support: may be used directly in jca-supporting
> application
> servers such as JBoss.
>
> XA transactions with true two phase commit when used as a jca resource
> adapter in a managed environment (with a
>
> TransactionManager and jca deployment support).
>
> Includes optional internal connection pooling for standalone use and use
> in
> non-jca environments such as Tomcat
>
> 4.
>
> ObjectFactory implementation for use in environments with JNDI but no
> TransactionManager such as Tomcat 4.
>
> DataSource implementations with or without pooling.
>
> Driver implementation for use in legacy applications.
>
> Complete access to all Firebird database parameter block and transaction
> parameter block settings.
>
> Optional integrated logging through log4j.
>
> JMX mbean for database management (so far just database create and drop).
>
>
>
> The following optional features are NOT supported:
>
> Batch Updates.
> Scrollable cursors.
> Updatable cursors.
> Cursors/Positioned update/delete
> Ref, Clob and Array types
> User Defined Types/Type Maps.
>
> The methods that support those features return SQLExceptions when used.
>
> In addition to the non supported features above, the following methods
> are
> not implemented:
>
> java.sql.ResultSetMetaData
> isReadOnly(i)
> isWritable(i)
> isDefinitivelyWritable(i)
> java.sql.Statement
> setEscapeProcessing(boolean)
> cancel()
> java.sql.PreparedStatement
> setObject(index,object,type,scale)
> setCharacterStream(i)
> setDate(i,date,calendar)
> setTime(i,time,calendar)
> setTimestamp(i,timestamp,calendar)
> java.sql.ResultSet
> getDate(i,calendar)
> getTime(i,calendar)
> getTimestamp(i,calendar)
>
> The following methods are implemented but do not work as expected
>
> java.sql.ResultSet
> get/setFetchSize does nothing
> java.sql.Statement
> get/setFetchSize does nothing
> get/setMaxFieldSize does nothing
> get/setQueryTimeout does nothing
> java.sql.PreparedStatement
> setObject(index,object,type) This method is supported but behaves as
> setObject(index,object)
>
>
> ********************************************************
>
> 3- Where to get the driver
>
> ********************************************************
>
> In your browser go to:
>
> http://sourceforge.net/projects/firebird/
>
> scroll down the page and find the row containing:
>
> firebird-jca-jdbc-driver
>
> Click the link "Download" in the rightmost column of the table in that
> row.
> This links you to another page
>
> with the zip files of the various versions of the driver available to be
> downloaded. The driver will have the
>
> heading "firebird-jca-jdbc-driver". Click on the version you wish to
> download. It looks something like:
>
> FirebirdSQL-1.x.zip.
>
> This will download the driver files to your system. Unzip the file and
> copy
> the contents to the appropriate
>
> directories on your system as described in #4 "Installing the Driver"
> below.
>
> More recent bugfix versions of the driver can be obtained by downloading
> the
> daily snapshot of the project
>
> through CVS and building the project. See #13 below for details.
>
>
> ********************************************************
>
> 4- Installing the Driver
>
> ********************************************************
>
> The classes from firebirdsql.jar must be in the classpath of the Java
> application being compiled, or otherwise
>
> made available to your application. The classes from the following
> packages
> must also be available:
>
> concurrent.jar
> connector.jar
> jaas.jar
> jta-spec1_0_1.jar
> log4j-core.jar (if you want logging available)
>
> either the jdbc 2 or 3 classes.
>
> These archives are included in the binary package.
>
> You can use the jmx management mbean either in a jmx agent (MBeanServer)
> or
> as a standalone class. So far it
>
> has been tested in jbossmx and the jmxri, although since it is extremely
> simple it should have no problems in
>
> any jmx implementation. Use of jbossmx is highly recommended due to its
> smaller bug count and because it is in
>
> active development.
>
> For use in a managed environment as a jca resource adapter, deploy
> firebirdsql.rar according to the
>
> environment's deployment mechanism.
>
> For installation in Tomcat, JBoss, JBuilder, and for use with stand alone
> Java programs see the corresponding
>
> sections below.
>
>
>
> ********************************************************
>
> 5- Connection Pooling
>
> ********************************************************
>
> The JCA-JDBC Driver features built-in connection pooling. This is very
> useful because it eliminates the need
>
> for external connection pooling routines like Poolman or DBCP.
>
> Setting up and shutting down JDBC connections to databases tend to be
> very
> time and CPU intensive operations.
>
> Connection pooling allows connections to be stored and re-used by
> applications, or even by different
>
> applications without going through the time consuming task of setting up
> the
> connection again.
>
> Using a connection pool effectively while preventing data corruption and
> unauthorized access requires a
>
> slightly different mindset.
>
> The Firebird database uses the concept of user logins. To access the
> database a user must log in and provide a
>
> password that the database recognizes. This is set up by the database
> administrator.
>
> This can lead to problems with a connection pool. Suppose "joe" logs in
> using his password and works with the
>
> database. If he logs out and his connection is kept alive and given to
> the
> next user, "bob", without
>
> re-authorizing, "bob" may be able to see confidential data that he is not
> intended to see. Worse he can change
>
> or delete data he should not have access to.
>
> If we only allow users to use connections previously opened with their
> username, we drastically reduce the
>
> effectiveness of the pool.
>
> To make the pool most effective we have to login with the same username
> every time. This requires us to manage
>
> the user access to the database in our code rather that allowing Firebird
> to
> do it for us. This is usually
>
> accomplished by creating a table of usernames, passwords, and roles
> separate
> from those maintained by the
>
> database.
>
> When a user logs in, all database access is done under a single username
> and
> password known to Firebird, for
>
> example username "calendar", password "calpass". The program then opens
> a
> user table created for the
>
> application and retrieves the username, password, and role of the user,
> which might be "joe", "joespassword",
>
> and "manager". The retrieved username and password is compared by your
> program to those provided by the user.
>
> If they match, your program allows the user to perform actions on the
> database allowed for users with their
>
> role, all under the Firebird username of "calendar".
>
> When the next user, "bob", logs in, transactions are still done with your
> program using the connection opened
>
> with the "calendar" Firebird username with the database, but the program
> checks the "bob" password and role in
>
> the application user table before allowing transactions.
>
> This results in maximum efficiency of connection pools. It is also
> compatibe with the way that web application
>
> servers handle container managed security. So even if your program
> starts
> out as a standalone Java program,
>
> you can "webify" the database access part of it very easily.
>
> Be aware that the JCA-JDBC Driver provides no encryption. If you use the
> driver in a standalone Java program,
>
> anyone who can listen to your network connection can see your usernames,
> passwords, and data as it crosses the
>
> net. You must take steps to secure your data. You can do this by all the
> standard methods: Secure networks,
>
> VPN, etc.
>
> A popular way to provide wide acess to your database while still
> providing
> security is to write your
>
> application as a web application that is viewed in a browser, rather than
> as
> a stand-alone application. Then
>
> you can restrict your web app to running under secure HTTP.
>
> If you are using the driver in stand-alone Java applications there is
> little
> need to use anything other than
>
> the built-in pooling.
>
> However, in some cases, you may not want to use the built-in connection
> pooling. If you are using the driver
>
> with a J2EE server that manages connection pooling, like JBoss, you are
> probably better off to let the
>
> container manage the pooling.
>
> In such cases the container (J2EE Server) can manage the pooling more
> efficiently for several different web
>
> applications that use the driver. Certain internal functions of the J2EE
> Container may be dependent on its
>
> internal pooling. Bypassing it may cause problems.
>
> In such a web application server environment, the server system's memory
> can
> be quickly overburdened if large
>
> numbers of sessions are started, each with their own copy of the driver
> and
> their own pool. Extra load is also
>
> placed on the CPU when each session has to perform its own connection and
> pool setup rather than using a single
>
> pooled setup.
>
> If you are using a limited J2EE server you may need to use the built-in
> pooling. Versions of Tomcat before 4.1
>
> are an example. From version 4.1, Tomcat has provided connection pooling
> via DBCP. Tomcat is a Servlet and
>
> Java Server Pages (JSP) server, but does not provide full J2EE web
> application server suport.
>
> Since a large number of installations use only servlets and JSP's,
> application servers like Tomcat, JRun, Cold
>
> Fusion, Servlet Exec, and Resin have become very popular. These have
> varying support for connection pooling.
>
> You will have to check the features of the particular version of your app
> server to see if pooling is offered
>
> or if you will need to use the built-in pool from the Driver.
>
> See the sections below on JBoss, Tomcat, and Using the Driver in Java
> code
> for specific information on those
>
> environments.
>
>
>
> ********************************************************
>
> 6- Using the Driver in Java Code
>
> ********************************************************
>
>
> Two forms of the driver can be used. FBDriver is used much like the old
> Interclient driver.
>
> FBWrappingDataSource has internal connection pooling capability. Example
> of
> both are included here.
>
> The driver supports two URL syntax formats:
>
> Standard format= jdbc:firebirdsql:[//host[:port]/]<database>
> FB old format= jdbc:firebirdsql:[host[/port]:]<database>
>
>
> For all environments that do not support jca deployment, make the classes
> in
> firebirdsql.jar available to your
>
> application. You will probably have to use some of the jars mentioned
> above
> as necessary.
>
>
> For use in a somewhat managed environment with JNDI but no jca support or
> transaction manager, use the
>
> FBDataSourceObjectFactory to bind a reference to a DataSource into jndi.
> Tomcat 4 is an example of this
>
> scenario. The JNDI implementation must support use of
> References/Referenceable. This will not work if the JNDI
>
> implementation only supports binding serialized objects.
>
>
> For use in a standalone application that only needs one connection, use
> either FBWrappingDataSource or
>
> FBDriver.
>
> A typical use of the FBDriver class would use code something like this:
>
> Class.forName("org.firebirdsql.jdbc.FBDriver");
>
> Connection conn =
> DriverManager.getConnection("jdbc:firebirdsql:localhost/3050:/firebird/test.
> gdb", "sysdba",
>
> "masterkey");
>
>
> or in windows
>
> DriverManager.getConnection("jdbc:firebirdsql:localhost/3050:E:\\database\\c
> arwash.gdb", "sysdba",
>
> "masterkey");
>
> For use in a standalone application with multiple connections that would
> benefit from connection pooling, use
>
> an instance of FBWrappingDataSource configured for pooling.
>
> A simple example is listed below:
>
>
> boolean FBDriverLoaded=false;
>
>
> if (!FBDriverLoaded)
> { // don't load the driver more than once.
> try
> {
> org.firebirdsql.jdbc.FBWrappingDataSource fbwds = new
> org.firebirdsql.jdbc.FBWrappingDataSource();
> }
> catch (ResourceException e)
> {
> System.out.println("Could Not create
> org.firebirdsql.jdbc.FBWrappingDataSource, error:"+e+"\n");
> }
>
> interclientLoaded = true;
>
>
> fbwds.setDatabaseName("//localhost:3050/dir1/subdir/myDatabase.gdb");
>
> // an old format version of the same url
> //
> fbwds.setDatabaseName("localhost/3050:/dir1/subdir/myDatabase.gdb");
>
> fbwds.setUser("sysdba");
> fbwds.setPassword("masterkey");
> fbwds.setIdleTimeoutMinutes(30);
>
>
> fbwds.setPooling(true); // this turns on pooling for this data
> source. Max and min must be set.
>
> fbwds.setMinSize(5); // this sets the minimum number of
> connections
> to keep in the pool
> fbwds.setMaxSize(30); // this sets the maximum number of
> connections
> that can be open at one time.
>
> try
> {
> fbwds.setLoginTimeout(10);
> }
> catch (SQLException e)
> {
> System.out.println("Could not set Login Timout in
> SQLDriver\n");
> }
> }
> else
> {
> //System.out.println("Firebird Driver already exists, not
> reloaded.\n");
> }
>
>
> Connection c;
>
> try
> {
> c = fbwds.getConnection();
> }
> catch (SQLException e)
> {
> system.out.println("getting new fbwds connection failed! Error:
> "+e+"\n");
> handleError(e);
> }
>
>
> // Use the connection "c" like any other connection then close it.
>
>
> c.close();
>
> // closing c returns it to the pool.
>
>
> Be aware that no security or encryption is built into the driver. If you
> use stand-alone Java programs you
>
> must provide secure access to your database to protect your passwords and
> data.
>
> More Java code for a driver example and a DataSource example are included
> in
> the #19 Code Examples section
>
> below.
>
>
>
> ********************************************************
>
> 7- Using the Driver with JBoss
>
> ********************************************************
>
>
> Deployment in JBoss 3 beta2 and later:
>
> The additional jars/classes mentioned above are already available in
> JBoss.
> Put firebirdsql.rar in the deploy
>
> directory. Get firebird-service.xml from jboss cvs (or the distribution
> when
> available) at
>
> connector[jbosscx]/src/etc/example-config/firebird-service.xml and modify
> the URL to point to the desired
>
> database location. Add a security domain to auth.conf of the form:
>
>
> FirebirdDBRealm {
>
> //
>
> // Security domain for new jca framework.
>
> // One per ManagedConnectionFactory are required.
>
> org.jboss.resource.security.ConfiguredIdentityLoginModule required
>
> principal="sysdba"
>
> userName="sysdba"
>
> password="masterkey"
>
> managedConnectionFactoryName="jboss.jca:service=XaTxCM,name=FirebirdDS"
>
> ;
>
> };
>
>
> where FirebirdDBRealm exactly matches the SecurityDomainJndiName
> attribute
> of your ConnectionManager mbean
>
> configuration and the managedConnectionFactoryName exactly matches the
> object name of the ConnectionManager
>
> mbean.
>
> If you see log messages such as principal=null when trying to get a
> connection, you have the wrong
>
> managedConnectionFactoryName. If you see attempts to use
> UserRolesLoginModule, you have mismatched
>
> SecurityDomainJndiName. Other login modules supporting multiple user
> login
> should be available in JBoss soon.
>
>
>
> ********************************************************
>
> 8- Using the Driver with Tomcat
>
> ********************************************************
>
> CATALINA_HOME is the installation directory for Tomcat 4.x or greater.
> An
> environment variable of that name is
>
> set up on the Tomcat server. TOMCAT_HOME was used in versions before
> Tomcat
> 4.
>
> To use the driver with Tomcat You must put the jar files where your web
> apps
> can access them. Once they are
>
> available to you web apps you use the driver in your servlets or beans
> just
> as you would in standalone
>
> programs.
>
> If you have only one webapp using the drivers or you need to keep the
> drivers separate from other web apps, put
>
> the jar files in the WEB-INF/lib/ subdirectory of your web app.
>
> It is more likely that Firebird will be used by all of your web apps and
> Tomcat itself. To have universal
>
> access to the drivers put the jars in CATALINA_HOME/common/lib/.
>
> If you configure a JNDI entry in CATALINA_HOME/conf/server.xml to use
> FBDataSourceObjectFactory, and you
>
> configure DBCP connection pooling (in Tomcat 4.1.x or greater) only one
> connection pool is started for all web
>
> apps. However, some users have reported problems with DBCP under certain
> circumstances.
>
> To use the driver's internal connection pooling, you can configure an
> FBWrapping Data Source for pooling just
>
> as you would in a stand alone program. If you put a class for doing that
> in
> a servlet and start it when Tomcat
>
> is initialized, you can share a pool among web applications. If you do
> this
> take care to make it thread safe
>
> and synchronize access to methods.
>
> Tomcat can also use Firebird for BASIC or FORM based user authentication.
> See the Tomcat docs for more
>
> details. An example realm for this is listed below. This goes in the
> CATALINA_HOME/conf/server.xml file.
>
>
> <Realm className="org.apache.catalina.realm.JDBCRealm" debug="0"
> driverName="org.firebirdsql.jdbc.FBDriver"
> userNameCol="USER_NAME"
> connectionName="sysdba"
> userTable="USERS"
> userCredCol="USER_PASS"
> validate="true"
>
> connectionURL="jdbc:firebirdsql:localhost/3050:/dir1/subdir/usersdb.gdb"
> userRoleTable="USER_ROLES"
> roleNameCol="ROLE_NAME"
> connectionPassword="masterkey"/>
>
> If your web app is set up to allow Tomcat to authenticate users this
> tells
> Tomcat to use Firebird to look up
>
> user names ans passwords. It does this by calling the Firebird driver
> FBDriver to login to a database named
>
> usersdb.gdb located on localhost in the directory /dir/subdir/, using the
> username sysdba and the password
>
> masterkey.
>
> Tomcat then takes the username that is typed into the browser by the
> person
> logging into the web app and
>
> searches the table named USERS to see if it is in the field USER_NAME of
> a
> record. If it is, it checks to see
>
> if the password typed into the browser is the same as the one in the
> field
> USER_PASS for that record. If it
>
> is, the user is allowed to login and Tomcat opens the table USER_ROLES
> and
> searches for all entries with
>
> USER_NAME. For each record it finds, it looks in the ROLE_NAME column
> and
> adds that role name to a list of
>
> roles for the user. It then allows access to web apps based on the roles
> listed by the database.
>
> You can configure your web apps in WEB-INF/web.xml to only allow users
> with
> certain roles access to the web
>
> app. You can even use the role inside your JSP's to only draw certain
> parts
> of an HTML page if a user has the
>
> appropriate role. This alows you to customize each page based on a
> user's
> role.
>
> To use Tomcat's online GUI management web app to control your Tomcat
> installation, you must have the role
>
> "manager" in the USER_ROLES table under your name.
>
>
> See the Tomcat docs for more information.
>
>
>
> ********************************************************
>
> 9. Using the Pure Java JCA-JDBC Firebird Driver with JBuilder 6 Personal
>
> ********************************************************
>
> Last updated: 2002.04.11
>
> Thanks to Marcelo.lopezruiz for this section.
>
> If you have any comments/suggestions, drop me an mail at
> marcelo.lopezruiz@.... If you have some spare
>
> time, check out the rest of the site at
> http://www.xlprueba.com.ar/marce/index.htm.
>
> 1. First, download the .zip file from SourceForge and unzip it to a
> temporary directory.
>
> 2. Read the release_notes.html document.
>
> 3. Unless you are doing funny things with your JDK, you use the default
> JDK
> installed with JBuilder6. In this
>
> case, you will need to download the javax.sql.* package, named the JDBC
> 2.0
> Optional Package API (formerly
>
> known as the JDBC 2.0 Standard Extension API) from Sun, at
> http://java.sun.com/products/jdbc/download.html.
>
> Select the last option (option package binary), accept the license
> agreement, and download the .jar file.
>
> 4. Start JBuilder 6 Personal.
>
> 5. Create a new project (File | New Project...). Select a directory and a
> project name, then click Next. In
>
> step 2, select the Required Libraries tab - here, the required libraries
> will be registered with JBuilder and
>
> then added to the project.
>
> 6. Click the Add button. A list of libraries JBuilder is aware of will be
> shown. Click the New button to
>
> register the required libraries. Enter FireBird JCA-JDBC in the Name
> field,
> select JBuilder in the Location
>
> combo box, and click the Add button. Select the firebirdsql.jar you
> unzipped, and click OK. Click OK again to
>
> close the library. Verify that the new library is selected, and click OK
> to
> close the "Select One or More
>
> Libraries" dialog box.
>
> 7. Repeat the previous steps with the following libraries, found in the
> lib
> subdirectory of the binary
>
> distribution (except for the last package, which you downloaded from
> Sun).
> concurrent.jar, named Concurrency Utilities
> connector.jar, named Connector
> jta-spec1_0_1.jar, named Java Transaction API
> jdbc2_0-stdext.jar, named JDBC 2 Optional Package
>
> 8. Click Next, enter the desired project information, and click Finish.
>
> 9. Create a new application (File | New, then Application in the New
> tab).
> Enter the information you want for
>
> your application, and complete the wizard.
>
> 10. Click on the Design tab, and double-click on the button with the
> opening
> folder icon to create an event
>
> handler.
>
> 11. Type the following code for the event handler (note the small helper
> method above).
> private void feedback(String text) {
> statusBar.setText(text);
> }
>
> void jButton1_actionPerformed(ActionEvent e) {
> // Hard-coded parameters
> String pathToDatabase = "C:\\Program
> Files\\Firebird\\examples\\EMPLOYEE.GDB";
> String userName = "sysdba";
> String password = "masterkey";
> String sql = "SELECT * FROM EMPLOYEE";
>
> // Load the FireBird driver.
> try {
> Class.forName("org.firebirdsql.jdbc.FBDriver");
> } catch(ClassNotFoundException cnfe) {
> feedback("org.firebirdsql.jdbc.FBDriver not found");
> return;
> }
>
> // Retrieve a connection.
> try {
> Statement stmt = null;
> ResultSet rst = null;
> Connection conn = DriverManager.getConnection(
> "jdbc:firebirdsql:localhost/3050:" + pathToDatabase, userName,
> password);
> try {
> // Create a statement and retrieve its result set.
> stmt = conn.createStatement();
> rst = stmt.executeQuery(sql);
> // Show the result set through the standard output.
> int columnCount = rst.getMetaData().getColumnCount();
> int recordIndex = 0;
> while(rst.next()) {
> recordIndex++;
> System.out.println("Record: " + recordIndex);
> for (int i=1;i<=columnCount;i++) {
> System.out.print(rst.getMetaData().getColumnName(i));
> System.out.print(": ");
> System.out.println(rst.getString(i));
> }
> }
> } finally {
> // close the database resources immediately, rather than waiting
> // for the finalizer to kick in later
> if (rst != null) rst.close();
> if (stmt != null) stmt.close();
> conn.close();
> }
> } catch(SQLException se) {
> feedback(se.toString());
> se.printStackTrace();
> }
> }
>
> 12. Type the following code at the beginning of the file, after the
> import
> statements.
> import java.sql.*;
>
> 13. Run the application, click the button, and view the output.
>
> 14. For the morbidly curious, the following link provides an overview of
> the
> classes offered by the
>
> concurrent.jar package.
> http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.h
> tml
>
> 15. When using this library, note that there are still unimplemented
> things.
> To view the source for the
>
> Connection class and check which methods will return null values or an
> unimplemented exception, see the
>
> following URL.
>
> http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/firebird/client-java/src/org/
> firebirdsql/jdbc/FBConnection.java?
>
> rev=HEAD&content-type=text/vnd.viewcvs-markup
>
>
>
> ********************************************************
>
> 10- Using Blobs
>
> ********************************************************
>
> Blobs are Binary Large OBjects. Blobs are used to store blocks of binary
> data of varying size in the database.
>
> An example would be a database table to store gif or jpeg images for a
> photo album program. Such a program
>
> could be written using the database to store file names of images files
> to
> be loaded from disk, but this could
>
> easily be corrupted if a file name were changed, a file inadvertently
> deleted, or the database moved to a
>
> system with different file naming conventions.
>
> Blobs allow the binary image data to be stored, retrieved, backed up, and
> migrated like any other database
>
> data.
>
> The Interclient JDBC driver did not implement many of the blob handling
> methods in the JDBC interfaces. So the
>
> programmer had limited tools for using blobs with Interclient. That is
> no
> longer the case with the JCA-JDBC
>
> driver. If you come across old code or help files dealing with blobs and
> Interbase/Interclient, be aware that
>
> it may be outdated and easier ways of dealing with blobs are available
> with
> the JCA-JDBC Driver.
>
> Firebird BLOB fields are accessed through different JDBC interfaces
> depending on their subtype. For subtype <0,
>
> they are accessed as Blob fields. Subtype 1 is a LongVarChar, and Subtype
> 2
> is LongVarBinary.
>
>
> Below is some example code written for use with Interclient that may be
> helpful.
>
> Storing BLOB Data:
>
> The example given below shows a method that inserts an array of bytes
> into a
> BLOB column in the database. The
>
> PreparedStatement class is used so we can set the parameters independant
> of
> the actual SQL command string.
>
> Example 2.0: Inserting a BLOB
>
> import java.io.*;
> import java.sql.*;
>
> ...
>
> public void insertBlob( int rowid, byte[] bindata ) {
>
> // In this example I'm assuming there's an open, active
> // Connection instance called 'con'.
>
> // This examples uses an imaginary SQL table of the following
> // form:
> //
> // CREATE TABLE blobs (
> // ROWID INT NOT NULL,
> // ROWDATA BLOB,
> //
> // PRIMARY KEY (rowid)
> // );
>
> try {
>
> ByteArrayInputStream bais = new ByteArrayInputStream(bindata);
>
> String sql = "INSERT INTO blobs ( rowid, rowdata ) VALUES ( ?, ?
> )";
>
> PreparedStatement ps = con.prepareStatement(sql);
>
> // Set up the parameter index for convenience (JDBC column
> // indices start from 1):
> int paramindex = 1;
>
> // Set the first parameter, the Row ID:
> ps.setInt(paramindex++, rowid);
>
> // Now set the actual binary column data by passing the
> // ByteArrayInputStream instance and its length:
> ps.setBinaryStream(paramindex++, bais, bindata.length);
>
> // Finally, execute the command and close the statement:
> ps.executeUpdate();
> ps.close();
>
> } catch ( SQLException se ) {
> System.err.println("Couldn't insert binary data: "+se);
> } catch ( IOException ioe ) {
> System.err.println("Couldn't insert binary data: "+ioe);
> } finally {
> con.close();
> }
> }
>
> Retrieving BLOB Data:
>
> The example given below shows a method that retrieves an array of bytes
> from
> the database.
>
> Example 2.0: Selecting a BLOB
>
> import java.io.*;
> import java.sql.*;
>
> ...
>
> public byte[] selectBlob( int rowid ) {
>
> // In this example I'm assuming there's an open, active
> // Connection instance called 'con'.
>
> // This examples uses an imaginary SQL table of the following
> // form:
> //
> // CREATE TABLE blobs (
> // ROWID INT NOT NULL,
> // ROWDATA BLOB,
> //
> // PRIMARY KEY (rowid)
> // );
>
> try {
>
> Statement sment = con.createStatement();
>
> String sql = "SELECT rowid, rowdata FROM blobs WHERE rowid = " +
> rowid;
>
> ResultSet rs = sment.executeQuery(sql);
>
> byte[] returndata = null;
>
> if ( rs.next() ) {
>
> try {
>
> // The ByteArrayOutputStream buffers all bytes written to it
> // until we call getBytes() which returns to us an array of
> bytes:
> ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
>
> // Create an input stream from the BLOB column. By default,
> rs.getBinaryStream()
> // returns a vanilla InputStream instance. We override this
> for
> efficiency
> // but you don't have to:
> BufferedInputStream bis = new BufferedInputStream(
> rs.getBinaryStream("fieldblob") );
>
> // A temporary buffer for the byte data:
> byte bindata[1024];
>
> // Used to return how many bytes are read with each read() of
> the input stream:
> int bytesread = 0;
>
> // Make sure its not a NULL value in the column:
> if ( !rs.wasNull() ) {
>
> if ( (bytesread = bis.read(bindata,0,bindata.length)) !=
> -1 )
> {
>
> // Write out 'bytesread' bytes to the writer instance:
> baos.write(bindata,0,bytesread);
>
> } else {
>
> // When the read() method returns -1 we've hit the end
> of
> the stream,
> // so now we can get our bytes out of the writer
> object:
> returndata = baos.getBytes();
>
> }
> }
>
> // Close the binary input stream:
> bis.close();
>
> } catch ( IOException ioe ) {
> System.err.println("Problem retrieving binary data: " + ioe);
> } catch ( ClassNotFoundException cnfe ) {
> System.err.println("Problem retrieving binary data: " +
> cnfe);
> }
> }
>
> rs.close();
> sment.close();
>
> } catch ( SQLException se ) {
> System.err.println("Couldn't retrieve binary data: " + se);
> } finally {
> con.close();
> }
>
> return returndata;
>
>
>
> ********************************************************
>
> 11- Using Multi-Byte Character Sets
>
> ********************************************************
>
>
> Character Encodings:
>
> Support for character encodings has just been added. This is easily
> accessible only from the FBDriver class. To
>
> use it, request a connection with a properties object containing a
> name-value pair lc_ctype=WIN1250 or other
>
> appropriate encoding name.
>
> URL-encoded params are fully supported only when you get a connection
> from
> java.sql.DriverManager (using
>
> FBDriver class). For example:
> jdbc:firebirdsql://localhost//home/databases/sample.gdb?lc_ctype=UNICODE_FSS
>
>
> It is also possible to set lc_ctype in a deployment descriptor by adding
> the following to your deployment
>
> descriptor:
>
> <config-property>
> <config-property-name>Encoding</config-property-name>
> <config-property-type>java.lang.String</config-property-type>
> <config-property-value>UNICODE_FSS</config-property-value>
> </config-property>
>
>
>
>
> ********************************************************
>
> 12- Reporting Bugs
>
> ********************************************************
>
>
> The developers attempt to follow the Firebird-Java@yahoogroups.com list.
> Join the list (see #16 below) and
>
> post information about suspected bugs. This is a good idea because what
> is
> often thought to be a bug turns out
>
> to be something else. List members may be able o help out and get you
> going
> again, whereas bug fixes might
>
> take awhile.
>
> You may also report bugs in the firebird bugtracker at:
> http://sourceforge.net/tracker/?group_id=9028&atid=109028
>
>
>
> ********************************************************
>
> 13- Obtaining Sources from SourceForge using CVS
>
> ********************************************************
>
> CVS is a source code control system for managing access to source code in
> a
> project that is being developed by
>
> multiple programmers. A full explanation of CVS is beyond the scope of
> this
> document, but information is
>
> available at sorceforge.net.
>
> To get the project containing the source from sourceforge, install CVS on
> your system and use it to download
>
> the module named "client-java". The user name is "anonymous".
>
> To build the source you will need several programs installed on your
> system.
> One is ant which can be
>
> downloaded from http://jakarta.apache.org/ant/index.html.
>
> Ant is a Java based build tool similar to make on Unix that uses xml
> files
> as its input files containing
>
> instructions for building a project.
>
> Ant, of course, requires that Java be installed on your system.
>
> If you use a GUI based CVS tool like WinCVS on Windows, be sure that you
> also have your system set up to run
>
> CVS from the command line.
>
> This is necessary because the newest version of the driver uses libraries
> from the JBoss project to avoid
>
> licensing issues related to distributing some libraries from Sun. The
> Ant
> build scripts use command line CVS
>
> to check out the code needed from the JBoss project.
>
> Once you install these tools and download the source, you should be able
> to
> go into the client-java folder
>
> (wherever you had CVS put it) and type "build" from the command line to
> build the driver.
>
> There is a file in the client-java directory called "build.bat" for
> Windows
> systems and one called "build.sh"
>
> for Unix systems. Under certain Unix shells you will have to type
> "build.sh" from the command line, the csh
>
> under Solaris for example.
>
>
>
>
> ********************************************************
>
> 14- Participating in the Development Project
>
> ********************************************************
>
>
>
> Use Firebird-Java@yahoogroups.com list to contact the developers about
> helping out (see #16 below). Perhaps the
>
> most crucial need right now is for more and better setup and usage
> guides,
> and to produce a reasonable section
>
> of the Firebird web site devoted to this driver. Work on this would be
> greatly appreciated.
>
>
>
> ********************************************************
>
> 15- Where to get help
>
> ********************************************************
>
> Firebird-Java@yahoogroups.com (see #16 below)
> www.IBPhoenix.com
>
> java.sun.com
>
>
>
> ********************************************************
>
> 16- Joining the Mailing List
>
> ********************************************************
>
> To join the Firebird-java mailing list, go to www.yahoogroups.com.
> Follow
> the instructions there for joining a
>
> group. The name of the group is Firebird-java.
>
> Please set your Yahoo settings to use plain text instead of HTML. All
> the
> ads drive some folks nuts and cause
>
> an automatic internet hookup for some folks in Europe who have to pay for
> outgoing phone calls.
>
>
> ********************************************************
>
> 17- Known Bugs
>
> ********************************************************
>
>
> You may report bugs in the firebird bugtracker at
> http://sourceforge.net/tracker/?group_id=9028&atid=109028
>
>
> ********************************************************
>
> 18- Additional JAR libraries needed to use the driver
>
> ********************************************************
>
>
> Certain Sun libraries are needed that are distributed with JDK 1.4
>
> Also:
>
> mini-j2ee.jar
> concurrent.jar
> jaas.jar
> log4j-core.jar (if you want logging available).
>
>
> ********************************************************
>
> 19- Code Examples
>
> ********************************************************
>
> There are two examples below, a driver example and a DataSource example.
> They are separated by a dashed line.
>
>
> Driver Example:
>
> // Original version of this file was part of InterClient 2.01 examples
> //
> // Copyright InterBase Software Corporation, 1998.
> // Written by com.inprise.interbase.interclient.r&d.PaulOstler :-)
> //
> // Code was modified by Roman Rokytskyy to show that Firebird JCA-JDBC
> driver
> // does not introduce additional complexity in normal driver usage
> scenario.
> //
> // A small application to demonstrate basic, but not necessarily simple,
> JDBC features.
> //
> // Note: you will need to hardwire the path to your copy of employee.gdb
> // as well as supply a user/password in the code below at the
> // beginning of method main().
>
> public class DriverExample
> {
> // Make a connection to an employee.gdb on your local machine,
> // and demonstrate basic JDBC features.
> // Notice that main() uses its own local variables rather than
> // static class variables, so it need not be synchronized.
> public static void main (String args[]) throws Exception
> {
> // Modify the following hardwired settings for your environment.
> // Note: localhost is a TCP/IP keyword which resolves to your local
> machine's IP address.
> // If localhost is not recognized, try using your local
> machine's
> name or
> // the loopback IP address 127.0.0.1 in place of localhost.
> String databaseURL =
> "jdbc:firebirdsql:localhost/3050:c:/database/employee.gdb";
> String user = "sysdba";
> String password = "masterkey";
> String driverName = "org.firebirdsql.jdbc.FBDriver";
>
> // As an exercise to the reader, add some code which extracts
> databaseURL,
> // user, and password from the program args[] to main().
> // As a further exercise, allow the driver name to be passed as well,
> // and modify the code below to use driverName rather than the
> hardwired
> // string "org.firebirdsql.jdbc.FBDriver" so that this code becomes
> // driver independent. However, the code will still rely on the
> // predefined table structure of employee.gdb.
>
> // See comment about closing JDBC objects at the end of this main()
> method.
> System.runFinalizersOnExit (true);
>
> // Here are the JDBC objects we're going to work with.
> // We're defining them outside the scope of the try block because
> // they need to be visible in a finally clause which will be used
> // to close everything when we are done.
> // The finally clause will be executed even if an exception occurs.
> java.sql.Driver d = null;
> java.sql.Connection c = null;
> java.sql.Statement s = null;
> java.sql.ResultSet rs = null;
>
> // Any return from this try block will first execute the finally
> clause
> // towards the bottom of this file.
> try {
>
> // Let's try to register the Firebird JCA-JDBC driver with the
> driver
> manager
> // using one of various registration alternatives...
> int registrationAlternative = 1;
> switch (registrationAlternative) {
>
> case 1:
> // This is the standard alternative and simply loads the driver
> class.
> // Class.forName() instructs the java class loader to load
> // and initialize a class. As part of the class initialization
> // any static clauses associated with the class are executed.
> // Every driver class is required by the jdbc specification to
> automatically
> // create an instance of itself and register that instance with
> the
> driver
> // manager when the driver class is loaded by the java class
> loader
> // (this is done via a static clause associated with the driver
> class).
> //
> // Notice that the driver name could have been supplied
> dynamically,
> // so that an application is not hardwired to any particular
> driver
> // as would be the case if a driver constructor were used, eg.
> // new org.firebirdsql.jdbc.FBDriver().
> try {
> Class.forName ("org.firebirdsql.jdbc.FBDriver");
> }
> catch (java.lang.ClassNotFoundException e) {
> // A call to Class.forName() forces us to consider this
> exception
> :-)...
> System.out.println ("Firebird JCA-JDBC driver not found in
> class
> path");
> System.out.println (e.getMessage ());
> return;
> }
> break;
>
> case 2:
> // There is a bug in some JDK 1.1 implementations, eg. with
> Microsoft
> // Internet Explorer, such that the implicit driver instance
> created
> during
> // class initialization does not get registered when the driver
> is
> loaded
> // with Class.forName().
> // See the FAQ at http://java.sun.com/jdbc for more info on this
> problem.
> // Notice that in the following workaround for this bug, that if
> the
> bug
> // is not present, then two instances of the driver will be
> registered
> // with the driver manager, the implicit instance created by the
> driver
> // class's static clause and the one created explicitly with
> newInstance().
> // This alternative should not be used except to workaround a JDK
> 1.1
> // implementation bug.
> try {
> java.sql.DriverManager.registerDriver (
> (java.sql.Driver) Class.forName
> ("org.firebirdsql.jdbc.FBDriver").newInstance ()
> );
> }
> catch (java.lang.ClassNotFoundException e) {
> // A call to Class.forName() forces us to consider this
> exception
> :-)...
> System.out.println ("Driver not found in class path");
> System.out.println (e.getMessage ());
> return;
> }
> catch (java.lang.IllegalAccessException e) {
> // A call to newInstance() forces us to consider this exception
> :-)...
> System.out.println ("Unable to access driver constructor, this
> shouldn't happen!");
> System.out.println (e.getMessage ());
> return;
> }
> catch (java.lang.InstantiationException e) {
> // A call to newInstance() forces us to consider this exception
> :-)...
> // Attempt to instantiate an interface or abstract class.
> System.out.println ("Unable to create an instance of driver
> class,
> this shouldn't happen!");
> System.out.println (e.getMessage ());
> return;
> }
> catch (java.sql.SQLException e) {
> // A call to registerDriver() forces us to consider this
> exception
> :-)...
> System.out.println ("Driver manager failed to register
> driver");
> showSQLException (e);
> return;
> }
> break;
>
> case 3:
> // Add the Firebird JCA-JDBC driver name to your system's
> jdbc.drivers property list.
> // The driver manager will load drivers from this system property
> list.
> // System.getProperties() may not be allowed for applets in some
> browsers.
> // For applets, use one of the Class.forName() alternatives
> above.
> java.util.Properties sysProps = System.getProperties ();
> StringBuffer drivers = new StringBuffer
> ("org.firebirdsql.jdbc.FBDriver");
> String oldDrivers = sysProps.getProperty ("jdbc.drivers");
> if (oldDrivers != null)
> drivers.append (":" + oldDrivers);
> sysProps.put ("jdbc.drivers", drivers.toString ());
> System.setProperties (sysProps);
> break;
>
> case 4:
> // Advanced: This is a non-standard alternative, and is tied to
> // a particular driver implementation, but is very flexible.
> //
> // It may be possible to configure a driver explicitly, either
> thru
> // the use of non-standard driver constructors, or non-standard
> // driver "set" methods which somehow tailor the driver to behave
> // differently from the default driver instance.
> // Under this alternative, a driver instance is created
> explicitly
> // using a driver specific constructor. The driver may then be
> // tailored differently from the default driver instance which is
> // created automatically when the driver class is loaded by the
> java
> class loader.
> // For example, perhaps a driver instance could be created which
> // is to behave like some older version of the driver.
> //
> // d = new org.firebirdsql.jdbc.FBDriver ();
> // DriverManager.registerDriver (d);
> // c = DriverManager.getConnection (...);
> //
> // Since two drivers, with differing behavior, are now registered
> with
> // the driver manager, they presumably must recognize different
> jdbc
> // subprotocols. For example, the tailored driver may only
> recognize
> // "jdbc:interbase:old_version://...", whereas the default driver
> instance
> // would recognize the standard "jdbc:interbase://...".
> // There are currently no methods, such as the hypothetical
> setVersion(),
> // for tailoring an Firebird JCA-JDBC driver so this 4th
> alternative
> is academic
> // and not necessary for Firebird JCA-JDBC driver.
> //
> // It is also possible to create a tailored driver instance which
> // is *not* registered with the driver manager as follows
> //
> // d = new org.firebirdsql.jdbc.FBDriver ();
> // c = d.connect (...);
> //
> // this is the most usual case as this does not require differing
> // jdbc subprotocols since the connection is obtained thru the
> driver
> // directly rather than thru the driver manager.
> d = new org.firebirdsql.jdbc.FBDriver ();
> }
>
> // At this point the driver should be registered with the driver
> manager.
> // Try to find the registered driver that recognizes interbase
> URLs...
> try {
> // We pass the entire database URL, but we could just pass
> "jdbc:interbase:"
> d = java.sql.DriverManager.getDriver (databaseURL);
> System.out.println ("Firebird JCA-JDBC driver version " +
> d.getMajorVersion () +
> "." +
> d.getMinorVersion () +
> " registered with driver manager.");
> }
> catch (java.sql.SQLException e) {
> System.out.println ("Unable to find Firebird JCA-JDBC driver
> among
> the registered drivers.");
> showSQLException (e);
> return;
> }
>
> // Advanced info: Class.forName() loads the java class for the
> driver.
> // All JDBC drivers are required to have a static clause that
> automatically
> // creates an instance of themselves and registers that instance
> // with the driver manager. So there is no need to call
> // DriverManager.registerDriver() explicitly unless the driver
> allows
> // for tailored driver instances to be created (each instance
> recognizing
> // a different jdbc sub-protocol).
>
> // Now that Firebird JCA-JDBC driver is registered with the driver
> manager,
> // try to get a connection to an employee.gdb database on this
> local
> machine
> // using one of two alternatives for obtaining connections...
> int connectionAlternative = 1;
> switch (connectionAlternative) {
>
> case 1:
> // This alternative is driver independent;
> // the driver manager will find the right driver for you based on
> the jdbc subprotocol.
> // In the past, this alternative did not work with applets in
> some
> browsers because of a
> // bug in the driver manager. I believe this has been fixed in
> the
> jdk 1.1 implementations.
> try {
> c = java.sql.DriverManager.getConnection (databaseURL, user,
> password);
> System.out.println ("Connection established.");
> }
> catch (java.sql.SQLException e) {
> System.out.println ("Unable to establish a connection through
> the
> driver manager.");
> showSQLException (e);
> return;
> }
> break;
>
> case 2:
> // If you're working with a particular driver d, which may or may
> not be registered,
> // you can get a connection directly from it, bypassing the
> driver
> manager...
> try {
> java.util.Properties connectionProperties = new
> java.util.Properties ();
> connectionProperties.put ("user", user);
> connectionProperties.put ("password", password);
> c = d.connect (databaseURL, connectionProperties);
> System.out.println ("Connection established.");
> }
> catch (java.sql.SQLException e) {
> System.out.println ("Unable to establish a connection through
> the
> driver.");
> showSQLException (e);
> return;
> }
> break;
> }
>
> // Let's disable the default autocommit so we can undo our changes
> later...
> try {
> c.setAutoCommit (false);
> System.out.println ("Auto-commit is disabled.");
> }
> catch (java.sql.SQLException e) {
> System.out.println ("Unable to disable autocommit.");
> showSQLException (e);
> return;
> }
>
> // Now that we have a connection, let's try to get some meta
> data...
> try {
> java.sql.DatabaseMetaData dbMetaData = c.getMetaData ();
>
> // Ok, let's query a driver/database capability
> if (dbMetaData.supportsTransactions ())
> System.out.println ("Transactions are supported.");
> else
> System.out.println ("Transactions are not supported.");
>
> // What are the views defined on this database?
> java.sql.ResultSet tables = dbMetaData.getTables (null, null,
> "%",
> new String[] {"VIEW"});
> while (tables.next ()) {
> System.out.println (tables.getString ("TABLE_NAME") + " is a
> view.");
> }
> tables.close ();
> }
> catch (java.sql.SQLException e) {
> System.out.println ("Unable to extract database meta data.");
> showSQLException (e);
> // What the heck, who needs meta data anyway ;-(, let's continue
> on...
> }
>
> // Let's try to submit some static SQL on the connection.
> // Note: This SQL should throw an exception on employee.gdb because
> // of an integrity constraint violation.
> try {
> s = c.createStatement ();
> s.executeUpdate ("update employee set salary = salary + 10000");
> }
> catch (java.sql.SQLException e) {
> System.out.println ("Unable to increase everyone's salary.");
> showSQLException (e);
> // We expected this to fail, so don't return, let's keep going...
> }
>
> // Let's submit some static SQL which produces a result set.
> // Notice that the statement s is reused with a new SQL string.
> try {
> rs = s.executeQuery ("select full_name from employee where salary
> <
> 50000");
> }
> catch (java.sql.SQLException e) {
> System.out.println ("Unable to submit a static SQL query.");
> showSQLException (e);
> // We can't go much further without a result set, return...
> return;
> }
>
> // The query above could just as easily have been dynamic SQL,
> // eg. if the SQL had been entered as user input.
> // As a dynamic query, we'd need to query the result set meta data
> // for information about the result set's columns.
> try {
> java.sql.ResultSetMetaData rsMetaData = rs.getMetaData ();
> System.out.println ("The query executed has " +
> rsMetaData.getColumnCount () +
> " result columns.");
> System.out.println ("Here are the columns: ");
> for (int i = 1; i <= rsMetaData.getColumnCount (); i++) {
> System.out.println (rsMetaData.getColumnName (i) +
> " of type " +
> rsMetaData.getColumnTypeName (i));
> }
> }
> catch (java.sql.SQLException e) {
> System.out.println ("Unable to extract result set meta data.");
> showSQLException (e);
> // What the heck, who needs meta data anyway ;-(, let's continue
> on...
> }
>
> // Ok, lets step thru the results of the query...
> try {
> System.out.println ("Here are the employee's whose salary <
> $50,000");
> while (rs.next ()) {
> System.out.println (rs.getString ("full_name"));
> }
> }
> catch (java.sql.SQLException e) {
> System.out.println ("Unable to step thru results of query");
> showSQLException (e);
> return;
> }
>
> // As an exercise to the reader, rewrite this code so that required
> // table structures are created dynamically using executeUpdate()
> on
> DDL.
> // In this way the code will be able to run against any database
> file
> rather
> // than just a previously setup employee.gdb.
> // Just to get you started, you'll want to define a method
> something
> like
> // the following...
> //
> // private static void createTableStructures (java.sql.Connection
> c)
> throws java.sql.SQLException
> // {
> // // Some drivers don't force commit on DDL, Firebird JCA-JDBC
> driver does,
> // // see DatabaseMetaData.dataDefinitionCausesTransactionCommit().
> // // This is not necessary for Firebird JCA-JDBC driver, but may
> be
> for other drivers...
> // c.setAutoCommit (true);
> //
> // java.sql.Statement s = c.createStatement();
> //
> // // Drop table EMPLOYEE if it already exists, if not that's ok
> too.
> // try { s.executeUpdate ("drop table EMPLOYEE"); } catch
> (java.sql.SQLException e) {}
> //
> // // Ok, now that we're sure the table isn't already there,
> create
> it...
> // s.executeUpdate ("create table EMPLOYEE (...)");
> //
> // // Ok, now populate the EMPLOYEE table...
> // s.executeUpdate ("insert into EMPLOYEE values (...)");
> //
> // s.close();
> // c.setAutoCommit (false);
> // }
> //
> }
>
> // This finally clause will be executed even if "return" was called
> in
> case of any exceptions above.
> finally {
> System.out.println ("Closing database resources and rolling back
> any
> changes we made to the database.");
>
> // Now that we're all finished, let's release database resources.
> try { if (rs!=null) rs.close (); } catch (java.sql.SQLException e)
> {
> showSQLException (e); }
> try { if (s!=null) s.close (); } catch (java.sql.SQLException e) {
> showSQLException (e); }
>
> // Before we close the connection, let's rollback any changes we
> may
> have made.
> try { if (c!=null) c.rollback (); } catch (java.sql.SQLException e)
> { showSQLException (e); }
> try { if (c!=null) c.close (); } catch (java.sql.SQLException e) {
> showSQLException (e); }
>
> // If you don't close your database objects explicitly as above,
> // they may be closed by the object's finalizer, but there's
> // no guarantee if or when the finalizer will be called.
> // In general, object finalizers are not called on program exit.
> // It's recommended to close your JDBC objects explictly,
> // but you can use System.runFinalizersOnExit(true), as at the
> beginning
> // of this method main(), to force finalizers to be called before
> // program exit.
> }
> }
>
> // Display an SQLException which has occured in this application.
> private static void showSQLException (java.sql.SQLException e)
> {
> // Notice that a SQLException is actually a chain of SQLExceptions,
> // let's not forget to print all of them...
> java.sql.SQLException next = e;
> while (next != null) {
> System.out.println (next.getMessage ());
> System.out.println ("Error Code: " + next.getErrorCode ());
> System.out.println ("SQL State: " + next.getSQLState ());
> next = next.getNextException ();
> }
> }
> }
>
>
> -----------------------------------------------------------------
>
>
> Data Source Example
>
> // Original version of this file was part of InterClient 2.01 examples
> //
> // Copyright InterBase Software Corporation, 1998.
> // Written by com.inprise.interbase.interclient.r&d.PaulOstler :-)
> //
> // Code was modified by Roman Rokytskyy to show that Firebird JCA-JDBC
> driver
> // does not introduce additional complexity in normal driver usage
> scenario.
> //
> // An example of using a JDBC 2 Standard Extension DataSource.
> // The DataSource facility provides an alternative to the JDBC
> DriverManager,
> // essentially duplicating all of the driver manager's useful
> functionality.
> // Although, both mechanisms may be used by the same application if
> desired,
> // JavaSoft encourages developers to regard the DriverManager as a legacy
> // feature of the JDBC API.
> // Applications should use the DataSource API whenever possible.
> // A JDBC implementation that is accessed via the DataSource API is not
> // automatically registered with the DriverManager.
> // The DriverManager, Driver, and DriverPropertyInfo interfaces
> // may be deprecated in the future.
>
> import org.firebirdsql.jdbc.FBWrappingDataSource;
> import org.firebirdsql.jca.FBConnectionRequestInfo;
> import org.firebirdsql.gds.GDS;
>
> public final class DataSourceExample
> {
><br/><br/>(Message over 64 KB, truncated)