org.edg.security.voms.database
Class Sequence

java.lang.Object
  |
  +--org.edg.security.voms.database.Sequence

public final class Sequence
extends java.lang.Object

Provides well-behaving sequences for MySQL databases. Essentially a naive emulation of Oracle sequences. We need these because (1) MySQL tends to reuse deleted auto_increment values in InnoDB tables after a server restart, and that causes grave problems with the archive tables, and (2) some things are very hard to do with auto_increment; for example, consider the transaction counter used in Update and the ACL id counter in DBACL. For these counters, it is simply impossible to use MySQL auto_increment: The transaction counter does not correspond to any table. The ACL id counter is not unique: any number of rows (even none at all) may validly have the same id value in the ACL table. Of course, by defining auxiliary tables for each sequence it is possible to provide more-or-less well-behaving MySQL sequences, but that would be an even bigger hack than this simple solution.

Version:
$Name: v0_7_0 $
Author:
Karoly Lorentey

Field Summary
private static java.util.Map instances
          Contains each instance of the Sequence class, keyed by their names.
private static org.apache.log4j.Logger log
          Logger.
private  java.lang.String name
           
private static java.util.regex.Pattern tableSyntax
          Precompiled regular expression for safety-checking table and column names.
 
Constructor Summary
private Sequence(java.lang.String name)
          Initializes a new sequence.
 
Method Summary
 long currval()
          Emulates the currval function of Oracle's sequences in primitive SQL.
static Sequence getInstance(java.lang.String name)
          Get the Sequence with the given name.
 long nextval()
          Emulates the nextval function of Oracle's sequences in primitive SQL.
 java.lang.String toString()
           
 Sequence update(java.lang.String table, java.lang.String column)
          Update sequence value based on the maximum value in a column of a database table.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

log

private static final org.apache.log4j.Logger log
Logger.


instances

private static java.util.Map instances
Contains each instance of the Sequence class, keyed by their names.


name

private java.lang.String name

tableSyntax

private static final java.util.regex.Pattern tableSyntax
Precompiled regular expression for safety-checking table and column names. Matches normal identifiers.

Constructor Detail

Sequence

private Sequence(java.lang.String name)
Initializes a new sequence.

Parameters:
name - The name of the sequence.
Throws:
java.lang.RuntimeException - if a database error occured during initialization.
Method Detail

getInstance

public static Sequence getInstance(java.lang.String name)
Get the Sequence with the given name.

Parameters:
name - The name of the sequence.
Throws:
java.lang.RuntimeException - if a database error occured during initialization.

nextval

public long nextval()
             throws GeneralDatabaseException
Emulates the nextval function of Oracle's sequences in primitive SQL. Note that MySQL does not support autonomous transactions, so we must allocate a separate connection handle for reliable sequence management. This solution assigns a unique sequence number for both comitted and rolled back transactions, but can not support reliable currval since it can not guarantee that the sequence number stays the same in a session if some other session (thread) calls nextval.

GeneralDatabaseException

currval

public long currval()
             throws GeneralDatabaseException
Emulates the currval function of Oracle's sequences in primitive SQL. Note that this is an extremely naive implementation that gives incorrect results in a parallel environment. The only acceptable use of this method is querying the 'current' value of the transaction counter, where it is not important that 'currval' consistently returns the same value.

GeneralDatabaseException

update

public Sequence update(java.lang.String table,
                       java.lang.String column)
Update sequence value based on the maximum value in a column of a database table.

Parameters:
table - the name of the table to query
column - the name of the column in the given table to query
Returns:
the Sequence object itself (for chained method calls) Example:
   static final Sequence seq = new Sequence ("acl").update ("acl", "aid").update ("acld", "aid");
 
Throws:
java.lang.IllegalArgumentException - if a parameter contains an invalid SQL identifier
java.lang.RuntimeException - (unchecked!) if a database error or inconsistency occurs.

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object