package org.hivedb.management; import javax.sql.DataSource; import org.hivedb.HiveRuntimeException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; /** * Persistent numeric sequence generator. JdbcKeyAuthority is a thin wrapper * around DataFieldMaxValueIncrementer. JdbcKeyAuthority also takes * responsibility for issuing CREATE statements to initialize the sequence. * * @author Justin McCarthy (jmccarthy@cafepress.com) */ public class JdbcKeyAuthority implements KeyAuthority { DataFieldMaxValueIncrementer incrementer = null; private Class returnType = null; private Class keySpace = null; // Only used to issue CREATE TABLE private DataSource dataSource = null; /** * @param keySpace * A class that distinguishes this counter (the class name will * be mapped to a database table) * @param returnType * Type of the numeric keys this KeyAuthority generates (Integer * or Float) */ public JdbcKeyAuthority(Class keySpace, Class returnType) { this.keySpace = keySpace; this.returnType = returnType; } protected void setIncrementer(DataFieldMaxValueIncrementer incrementer) { this.incrementer = incrementer; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } protected DataSource getDataSource() { return this.dataSource; } public Object nextAvailableKey() { Object result = null; try { result = nextKey(); } catch (Exception ex) { createSchema(); result = nextKey(); } return result; } @SuppressWarnings("unchecked") private Object nextKey() { if (Integer.class.equals(returnType)) return new Integer(incrementer.nextIntValue()); if (Long.class.equals(returnType)) return new Long(incrementer.nextLongValue()); throw new HiveRuntimeException("Unable to generate key for type " + returnType.toString()); } protected void createSchema() { JdbcTemplate template = new JdbcTemplate(dataSource); template.execute("CREATE TABLE " + getKeyspaceTableName() + " (" + COLUMN_NAME + " int);"); template.execute("INSERT INTO " + getKeyspaceTableName() + " VALUES (1)"); } public static String COLUMN_NAME = "current_max_id"; protected String getKeyspaceTableName() { return tableNameForClass(keySpace); } public static String tableNameForClass(Class aClass) { return "key_authority_" + aClass.getName().toLowerCase().replace('.', '_').replace('$', '_'); } }