| 
              
                The driver supports prepared statements, but not callable ones. 
                 DatabaseMetaData.getIndexInfo and getPrimaryKeys are only partially 
                  supported. They correctly identify the indexes corresponding 
                  to any given table, together with the columns which are indexed. 
                  However, all other information returned by these routines simply 
                  takes a default value. This will be fixed in a future release.  The driver passes all of Sun's JDBC™ tests that were not specifically 
                  excluded because of its limited feature set.  InstantDB limits the number of simultaneously open ResultSets 
                  to one per Statement. As soon as a new SQL statment is executed, 
                  any existing ResultSet is closed. To access multiple ResultSets 
                  simultaneously, use multiple Statements. This is as per the 
                  JDBC™ specification. It is important to try and close ResultSets explicitly whenever 
                  possible. If the garbage collector tries to destroy an open 
                  ResultSet, then InstantDB's finalize method will try and close 
                  the ResultSet. This can lead to transaction access conflicts 
                  with the main thread in some virtual machines. This in turn 
                  can lead to deadlocks.  Non-Standard 
              Extensions 
              
              Properties idbConnection.getProperties() provides access 
                to the Properties supplied when the Connection was created by 
                the DriverManager class.  int idbStatement.getBatchCount() returns the number of 
                statements currently batched for execution.  Object idbConnection.getLastValueInserted(String tableName, 
                String columnName) returns the last value inserted into the 
                specified table and column. You should set auto commit off if 
                you are using this in a multi-threaded environment. That way you 
                can perform the explicit sequence: INSERT, getLastValueInserted(), 
                COMMIT.  The following extensions were created before JDBC™ 2.0 was 
                defined. On Java™ 2 platforms, it is recommended that the 
                JDBC™ 2.0 scrollable results set methods be used instead. 
               JDBC™ provides support for named cursors, which are not currently 
                supported by InstantDB. In order to provide a results set navigation 
                capability, InstantDB provides the following non-standard extensions: 
               
                int idbResultsSet.getRowCount() - returns the number 
                  of rows in the results set. 
                int idbResultsSet.getCurRow() - returns the number 
                  of the next row to be returned. This is always in the range 
                  1 to getRowCount(). 
                void idbResultsSet.setCurRow(int) - sets the next row 
                  that will be returned when ResultSet.next() is called. This 
                  must be in the range 1 to getRowCount(), or a SQLException gets 
                  thrown. 
               You only have to use these routines where you need to move around 
                a results set. An example might be where you want to populate 
                a list box more efficiently, or any other situation where the 
                data displayed is determined by user input. Normal ResultSet.next() 
                calls can be used without invoking any of these non-standard extensions. 
                The commsql 
                example program illustrates the use of these extensions.  
 Scrollable 
                Results Sets InstantDB supports both scrollable and updatable results sets. 
              However scroll sensistive results sets are not currently supported. 
             In fact when a statement is created, InstantDB ignores the results 
              sets type requested. All InstantDB results sets are scrollable, 
              updatable and insensitive (even to their own updates).  This means that, if you use a results set to update an underlying 
              table, you will not see that change refelected in the results set 
              itself. However, as soon as you query the table again, any updated 
              values will become visible in the new results set.  
 Memory 
              Management
  
              There are two basic approaches that JVMs™ can take to garbage 
                collection ("GC"). On the one hand, GC can take place synchronously, 
                where advantage can be taken of the current context to remove 
                any objects which have fallen out of scope. Alternatively, GC 
                can take place asynchronously. The latter approach has to work 
                harder to find objects eligible for destruction since its only 
                means of finding unreferenced objects is to scan them all - which 
                can take some time.  In order to help reduce memory growth, InstantDB makes every 
                effort to set unused object references to null. During extended 
                operations, such as table imports, InstantDB yields control to 
                allow asynchronous GC to take place.  A well written garbage collector will always find unreferenced 
                objects eventually - and that's the key point. There is 
                always some latency before asynchronous garbage collection kicks 
                in. Tests with InstantDB show that, on some JVMs™, this latency 
                can be surprisingly long. It can take up to two thousand (!!) 
                SQL requests before the database memory footprint reaches 
                a steady state (i.e. garbage gets found at the same rate it gets 
                generated).  In order to prevent run-away memory usage there are a few simple 
                rules you should follow.  
                 After you've finished with a ResultSet or Statement 
                  always call the object's close() method, set all references 
                  to the object to null and call System.gc(). 
                 Try to ensure that System.gc() gets called as close to the 
                  home of an object as possible. If a large object is about to 
                  go out of scope, set all references to it to null and call System.gc() 
                  before leaving the method. 
                 Try to allocate Vectors and Hashtables with 
                  sufficient room to hold all their elements right from the start. 
                  The growth of these objects will not only slow your program 
                  down, it will also leave more garbage lying around. 
                 Try not to get carried away doing String manipulations. 
                  Remember that Strings are immutable in Java™. Changing 
                  a String involves its deletion followed by the instantiation 
                  of a completely new String object. If you're performing a lot 
                  of string manipulation then use Stringbuffer rather than 
                  String. 
                 Try to reuse objects wherever possible. 
                 Make frequent calls to System.gc(), but not too frequent. 
                  Calling it too often, especially when memory is running low, 
                  will cause your program to slow down dramatically. 
               
              Following the above rules will reduce the memory footprint of your 
              applications, and, if done judiciously, will also make your Java™ 
              programs run faster.  |