| Method from org.apache.openjpa.jdbc.kernel.TableJDBCSeq Detail: |
protected Column addPrimaryKeyColumn(Table table) {
DBDictionary dict = _conf.getDBDictionaryInstance();
Column pkColumn = table.addColumn(dict.getValidColumnName
(getPrimaryKeyColumn(), table));
pkColumn.setType(dict.getPreferredType(Types.TINYINT));
pkColumn.setJavaType(JavaTypes.INT);
return pkColumn;
}
Add the primary key column to the given table and return it. |
public void addSchema(ClassMapping mapping,
SchemaGroup group) {
// Since the table is created by openjpa internally
// we can create the table for each schema within the PU
// in here.
Schema[] schemas = group.getSchemas();
for (int i = 0; i < schemas.length; i++) {
String schemaName = Strings.getPackageName(_table);
if (schemaName.length() == 0)
schemaName = Schemas.getNewTableSchema(_conf);
if (schemaName == null)
schemaName = schemas[i].getName();
// create table in this group
Schema schema = group.getSchema(schemaName);
if (schema == null)
schema = group.addSchema(schemaName);
schema.importTable(_pkColumn.getTable());
// we need to reset the table name in the column with the
// fully qualified name for matching the table name from the
// Column.
_pkColumn.resetTableName(schemaName + "."
+ _pkColumn.getTableName());
// some databases require to create an index for the sequence table
_conf.getDBDictionaryInstance().createIndexIfNecessary(schema,
_table, _pkColumn);
}
}
|
protected void allocateInternal(int count,
JDBCStore store,
ClassMapping mapping) throws SQLException {
Status stat = getStatus(mapping);
if (stat == null)
return;
while (true) {
int available;
synchronized (stat) {
available = (int) (stat.max - stat.seq);
if (available >= count)
return;
}
allocateSequence(store, mapping, stat, count - available, false);
}
}
|
protected Object currentInternal(JDBCStore store,
ClassMapping mapping) throws Exception {
if (current == null) {
Connection conn = getConnection(store);
try {
long cur = getSequence(mapping, conn);
if (cur != -1)
current = Numbers.valueOf(cur);
} finally {
closeConnection(conn);
}
}
return super.currentInternal(store, mapping);
}
|
public void dropTable() throws SQLException {
if (_log.isInfoEnabled())
_log.info(_loc.get("drop-seq-table"));
// drop the table
SchemaTool tool = new SchemaTool(_conf);
tool.setIgnoreErrors(true);
tool.dropTable(_pkColumn.getTable());
}
Drops the sequence table in the DB. |
public void endConfiguration() {
buildTable();
}
|
protected ResultSet executeQuery(JDBCConfiguration conf,
Connection conn,
PreparedStatement stmnt,
SQLBuffer buf) throws SQLException {
return stmnt.executeQuery();
}
This method is to provide override for non-JDBC or JDBC-like
implementation of executing query. |
protected int executeUpdate(JDBCConfiguration conf,
Connection conn,
PreparedStatement stmnt,
SQLBuffer buf,
int opcode) throws SQLException {
return stmnt.executeUpdate();
}
This method is to provide override for non-JDBC or JDBC-like
implementation of executing update. |
public int getAllocate() {
return _alloc;
}
Return the number of sequences to allocate for each update of the
sequence table. Sequence numbers will be grabbed in blocks of this
value to reduce the number of transactions that must be performed on
the sequence table. |
public JDBCConfiguration getConfiguration() {
return _conf;
}
|
public int getInitialValue() {
return _intValue;
}
Return the number as the initial number for the
GeneratedValue.TABLE strategy to start with. |
protected Object getPrimaryKey(ClassMapping mapping) {
return Numbers.valueOf(0);
}
Return the primary key value for the given class. |
public String getPrimaryKeyColumn() {
return _pkColumnName;
}
The name of the table's primary key column. Defaults to
ID. |
protected long getSequence(ClassMapping mapping,
Connection conn) throws SQLException {
if (_log.isTraceEnabled())
_log.trace(_loc.get("get-seq"));
Object pk = getPrimaryKey(mapping);
if (pk == null)
return -1;
DBDictionary dict = _conf.getDBDictionaryInstance();
SQLBuffer sel = new SQLBuffer(dict).append(_seqColumn);
SQLBuffer where = new SQLBuffer(dict).append(_pkColumn).append(" = ").
appendValue(pk, _pkColumn);
String tableName = resolveTableName(mapping, _seqColumn.getTable());
SQLBuffer tables = new SQLBuffer(dict).append(tableName);
SQLBuffer select = dict.toSelect(sel, null, tables, where, null, null,
null, false, dict.supportsSelectForUpdate, 0, Long.MAX_VALUE,
false, true);
PreparedStatement stmnt = prepareStatement(conn, select);
ResultSet rs = null;
try {
rs = executeQuery(_conf, conn, stmnt, select);
return getSequence(rs, dict);
} finally {
if (rs != null)
try { rs.close(); } catch (SQLException se) {}
if (stmnt != null)
try { stmnt.close(); } catch (SQLException se) {}
}
}
Return the current sequence value, or -1 if unattainable. |
protected long getSequence(ResultSet rs,
DBDictionary dict) throws SQLException {
if (rs == null || !rs.next())
return -1;
return dict.getLong(rs, 1);
}
This method is to provide override for non-JDBC or JDBC-like
implementation of getting sequence from the result set. |
public String getSequenceColumn() {
return _seqColumnName;
}
The name of the column that holds the sequence value. Defaults
to SEQUENCE_VALUE. |
protected TableJDBCSeq.Status getStatus(ClassMapping mapping) {
Status status = (Status)_stat.get(mapping);
if (status == null){
status = new Status();
_stat.put(mapping, status);
}
return status;
}
Return the appropriate status object for the given class, or null
if cannot handle the given class. The mapping may be null. |
public String getTable() {
return _table;
}
The sequence table name. Defaults to OPENJPA_SEQUENCE_TABLE.
By default, the table will be placed in the first schema listed in your
openjpa.jdbc.Schemas property, or in the default schema if
the property is not given. If you specify a table name in the form
<schema>.<table>, then the given schema
will be used. |
public static void main(String[] args) throws Exception {
Options opts = new Options();
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws Exception {
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
return TableJDBCSeq.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.out.println(_loc.get("seq-usage"));
}
Usage: java org.apache.openjpa.jdbc.schema.TableJDBCSequence [option]*
-action/-a <add | drop | get | set> [value]
Where the following options are recognized.
- -properties/-p <properties file or resource>: The
path or resource name of a OpenJPA properties file containing
information such as the license key and connection data as
outlined in JDBCConfiguration . Optional.
- -<property name> <property value>: All bean
properties of the OpenJPA JDBCConfiguration can be set by
using their names and supplying a value. For example:
-licenseKey adslfja83r3lkadf
The various actions are as follows.
- add: Create the sequence table.
- drop: Drop the sequence table.
- get: Print the current sequence value.
- set: Set the sequence value.
|
protected Object nextInternal(JDBCStore store,
ClassMapping mapping) throws Exception {
// if needed, grab the next handful of ids
Status stat = getStatus(mapping);
if (stat == null)
throw new InvalidStateException(_loc.get("bad-seq-type",
getClass(), mapping));
while (true) {
synchronized (stat) {
// make sure seq is at least 1, since autoassigned ids of 0 can
// conflict with uninitialized values
stat.seq = Math.max(stat.seq, 1);
if (stat.seq < stat.max)
return Numbers.valueOf(stat.seq++);
}
allocateSequence(store, mapping, stat, _alloc, true);
}
}
|
protected PreparedStatement prepareStatement(Connection conn,
SQLBuffer buf) throws SQLException {
return buf.prepareStatement(conn);
}
This method is to provide override for non-JDBC or JDBC-like
implementation of preparing statement. |
public void refreshTable() throws SQLException {
if (_log.isInfoEnabled())
_log.info(_loc.get("make-seq-table"));
// create the table
SchemaTool tool = new SchemaTool(_conf);
tool.setIgnoreErrors(true);
tool.createTable(_pkColumn.getTable());
}
Creates the sequence table in the DB. |
public String resolveTableName(ClassMapping mapping,
Table table) {
String sName = mapping.getTable().getSchemaName();
String tableName;
if (sName == null)
tableName = table.getFullName();
else
tableName = sName + "." + table.getName();
return tableName;
}
Resolve a fully qualified table name |
public static boolean run(JDBCConfiguration conf,
String[] args,
Options opts) throws Exception {
String action = opts.removeProperty("action", "a", null);
Configurations.populateConfiguration(conf, opts);
return run(conf, args, action);
}
Run the tool. Returns false if invalid options were given. |
public static boolean run(JDBCConfiguration conf,
String[] args,
String action) throws Exception {
if (args.length > 1 || (args.length != 0
&& !ACTION_SET.equals(action)))
return false;
TableJDBCSeq seq = new TableJDBCSeq();
String props = Configurations.getProperties(conf.getSequence());
Configurations.configureInstance(seq, conf, props);
if (ACTION_DROP.equals(action))
seq.dropTable();
else if (ACTION_ADD.equals(action))
seq.refreshTable();
else if (ACTION_GET.equals(action) || ACTION_SET.equals(action)) {
Connection conn = conf.getDataSource2(null).getConnection();
try {
long cur = seq.getSequence(null, conn);
if (ACTION_GET.equals(action))
System.out.println(cur);
else {
long set;
if (args.length > 0)
set = Long.parseLong(args[0]);
else
set = cur + seq.getAllocate();
if (set < cur)
set = cur;
else {
Status stat = seq.getStatus(null);
seq.setSequence(null, stat, (int) (set - cur), true,
conn);
set = stat.seq;
}
System.err.println(set);
}
}
catch (NumberFormatException nfe) {
return false;
} finally {
try { conn.close(); } catch (SQLException se) {}
}
} else
return false;
return true;
}
Run the tool. Return false if an invalid option was given. |
public void setAllocate(int alloc) {
_alloc = alloc;
}
Return the number of sequences to allocate for each update of the
sequence table. Sequence numbers will be grabbed in blocks of this
value to reduce the number of transactions that must be performed on
the sequence table. |
public void setConfiguration(Configuration conf) {
_conf = (JDBCConfiguration) conf;
_log = _conf.getLog(JDBCConfiguration.LOG_RUNTIME);
}
|
public void setIncrement(int inc) {
setAllocate(inc);
} Deprecated! Use - #setAllocate . Retained for backwards
compatibility of auto-configuration.
|
public void setInitialValue(int intValue) {
_intValue = intValue;
}
Set the initial number in the table for the GeneratedValue.TABLE
strategy to use as initial number. |
public void setPrimaryKeyColumn(String primaryKeyColumn) {
_pkColumnName = primaryKeyColumn;
}
The name of the table's primary key column. Defaults to
ID. |
protected boolean setSequence(ClassMapping mapping,
TableJDBCSeq.Status stat,
int inc,
boolean updateStatSeq,
Connection conn) throws SQLException {
if (_log.isTraceEnabled())
_log.trace(_loc.get("update-seq"));
Object pk = getPrimaryKey(mapping);
if (pk == null)
throw new InvalidStateException(_loc.get("bad-seq-type",
getClass(), mapping));
DBDictionary dict = _conf.getDBDictionaryInstance();
SQLBuffer where = new SQLBuffer(dict).append(_pkColumn).append(" = ").
appendValue(pk, _pkColumn);
// loop until we have a successful atomic select/update sequence
long cur = 0;
PreparedStatement stmnt;
ResultSet rs;
SQLBuffer upd;
for (int updates = 0; updates == 0;) {
stmnt = null;
rs = null;
try {
cur = getSequence(mapping, conn);
if (cur == -1)
return false;
// update the value
upd = new SQLBuffer(dict);
String tableName = resolveTableName(mapping, _seqColumn.getTable());
upd.append("UPDATE ").append(tableName).
append(" SET ").append(_seqColumn).append(" = ").
appendValue(Numbers.valueOf(cur + inc), _seqColumn).
append(" WHERE ").append(where).append(" AND ").
append(_seqColumn).append(" = ").
appendValue(Numbers.valueOf(cur), _seqColumn);
stmnt = prepareStatement(conn, upd);
updates = executeUpdate(_conf, conn, stmnt, upd, RowImpl.ACTION_UPDATE);
} finally {
if (rs != null)
try { rs.close(); } catch (SQLException se) {}
if (stmnt != null)
try { stmnt.close(); } catch (SQLException se) {}
}
}
// setup new sequence range
synchronized (stat) {
if (updateStatSeq && stat.seq < cur)
stat.seq = cur;
if (stat.max < cur + inc)
stat.max = cur + inc;
}
return true;
}
Grabs the next handful of sequence numbers. |
public void setSequenceColumn(String sequenceColumn) {
_seqColumnName = sequenceColumn;
}
The name of the column that holds the sequence value. Defaults
to SEQUENCE_VALUE. |
public void setTable(String name) {
_table = name;
}
The sequence table name. Defaults to OPENJPA_SEQUENCE_TABLE.
By default, the table will be placed in the first schema listed in your
openjpa.jdbc.Schemas property, or in the default schema if
the property is not given. If you specify a table name in the form
<schema>.<table>, then the given schema
will be used. |
public void setTableName(String name) {
setTable(name);
} Deprecated! Use - #setTable . Retained for
backwards-compatibility with auto-configuration.
|
public void startConfiguration() {
}
|