Depot implementation of the stat system persistence - hopefully schema compatible with the old version. This one is a little more complicated and Whirled doesn't have any stats yet so I was a little at a loss at how to test all of it. Perhaps somebody at Bang could make sure nothing crashes and burns horribly when e.g. a new string code is assigned?
git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@383 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// $Id: PuzzleManagerDelegate.java 209 2007-02-24 00:37:33Z mdb $
|
||||
//
|
||||
// Vilya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/vilya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.stats.server.persist;
|
||||
|
||||
import com.samskivert.jdbc.depot.Key;
|
||||
import com.samskivert.jdbc.depot.PersistentRecord;
|
||||
import com.samskivert.jdbc.depot.annotation.Column;
|
||||
import com.samskivert.jdbc.depot.annotation.Entity;
|
||||
import com.samskivert.jdbc.depot.annotation.Id;
|
||||
import com.samskivert.jdbc.depot.expression.ColumnExp;
|
||||
|
||||
@Entity(name="STAT_RECORD")
|
||||
public class StatRecord extends PersistentRecord
|
||||
{
|
||||
// AUTO-GENERATED: FIELDS START
|
||||
/** The column identifier for the {@link #playerId} field. */
|
||||
public static final String PLAYER_ID = "playerId";
|
||||
|
||||
/** The qualified column identifier for the {@link #playerId} field. */
|
||||
public static final ColumnExp PLAYER_ID_C =
|
||||
new ColumnExp(StatRecord.class, PLAYER_ID);
|
||||
|
||||
/** The column identifier for the {@link #statCode} field. */
|
||||
public static final String STAT_CODE = "statCode";
|
||||
|
||||
/** The qualified column identifier for the {@link #statCode} field. */
|
||||
public static final ColumnExp STAT_CODE_C =
|
||||
new ColumnExp(StatRecord.class, STAT_CODE);
|
||||
|
||||
/** The column identifier for the {@link #statData} field. */
|
||||
public static final String STAT_DATA = "statData";
|
||||
|
||||
/** The qualified column identifier for the {@link #statData} field. */
|
||||
public static final ColumnExp STAT_DATA_C =
|
||||
new ColumnExp(StatRecord.class, STAT_DATA);
|
||||
// AUTO-GENERATED: FIELDS END
|
||||
|
||||
public static final int SCHEMA_VERSION = 2;
|
||||
|
||||
/** The identifier of the player this is a stat for. */
|
||||
@Id
|
||||
@Column(name="PLAYER_ID")
|
||||
public int playerId;
|
||||
|
||||
/** The code of the stat. */
|
||||
@Id
|
||||
@Column(name="STAT_CODE")
|
||||
public int statCode;
|
||||
|
||||
/** The data associated with the stat. */
|
||||
@Column(name="STAT_DATA")
|
||||
public byte[] statData;
|
||||
|
||||
/**
|
||||
* An empty constructor for unmarshalling.
|
||||
*/
|
||||
public StatRecord ()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that populates all our fields.
|
||||
*/
|
||||
public StatRecord (int playerId, int statCode, byte[] data)
|
||||
{
|
||||
super();
|
||||
this.playerId = playerId;
|
||||
this.statCode = statCode;
|
||||
this.statData = data;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED: METHODS START
|
||||
/**
|
||||
* Create and return a primary {@link Key} to identify a {@link #StatRecord}
|
||||
* with the supplied key values.
|
||||
*/
|
||||
public static Key<StatRecord> getKey (int playerId, int statCode)
|
||||
{
|
||||
return new Key<StatRecord>(
|
||||
StatRecord.class,
|
||||
new String[] { PLAYER_ID, STAT_CODE },
|
||||
new Comparable[] { playerId, statCode });
|
||||
}
|
||||
// AUTO-GENERATED: METHODS END
|
||||
}
|
||||
@@ -5,28 +5,34 @@ package com.threerings.stats.server.persist;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Date;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.samskivert.io.ByteArrayOutInputStream;
|
||||
import com.samskivert.io.PersistenceException;
|
||||
import com.samskivert.jdbc.ConnectionProvider;
|
||||
import com.samskivert.jdbc.DatabaseLiaison;
|
||||
import com.samskivert.jdbc.JDBCUtil;
|
||||
import com.samskivert.jdbc.SimpleRepository;
|
||||
import com.samskivert.jdbc.depot.CacheInvalidator;
|
||||
import com.samskivert.jdbc.depot.DepotRepository;
|
||||
import com.samskivert.jdbc.depot.PersistenceContext;
|
||||
import com.samskivert.jdbc.depot.PersistentRecord;
|
||||
import com.samskivert.jdbc.depot.PersistenceContext.CacheEvictionFilter;
|
||||
import com.samskivert.jdbc.depot.annotation.Computed;
|
||||
import com.samskivert.jdbc.depot.annotation.Entity;
|
||||
import com.samskivert.jdbc.depot.clause.FieldOverride;
|
||||
import com.samskivert.jdbc.depot.clause.FromOverride;
|
||||
import com.samskivert.jdbc.depot.clause.QueryClause;
|
||||
import com.samskivert.jdbc.depot.clause.Where;
|
||||
import com.samskivert.jdbc.depot.expression.FunctionExp;
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
@@ -38,7 +44,7 @@ import static com.threerings.stats.Log.log;
|
||||
/**
|
||||
* Responsible for the persistent storage of per-player statistics.
|
||||
*/
|
||||
public class StatRepository extends SimpleRepository
|
||||
public class StatRepository extends DepotRepository
|
||||
implements Stat.AuxDataSource
|
||||
{
|
||||
/**
|
||||
@@ -56,7 +62,16 @@ public class StatRepository extends SimpleRepository
|
||||
public StatRepository (ConnectionProvider conprov)
|
||||
throws PersistenceException
|
||||
{
|
||||
super(conprov, STAT_DB_IDENT);
|
||||
this(new PersistenceContext(STAT_DB_IDENT, conprov));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new statistics repository with the specified persistence context.
|
||||
*/
|
||||
public StatRepository (PersistenceContext context)
|
||||
throws PersistenceException
|
||||
{
|
||||
super(context);
|
||||
|
||||
// load up our string set mappings
|
||||
loadStringCodes(null);
|
||||
@@ -65,43 +80,38 @@ public class StatRepository extends SimpleRepository
|
||||
/**
|
||||
* Loads the stats associated with the specified player.
|
||||
*/
|
||||
public ArrayList<Stat> loadStats (final int playerId)
|
||||
public ArrayList<Stat> loadStats (int playerId)
|
||||
throws PersistenceException
|
||||
{
|
||||
final ArrayList<Stat> stats = new ArrayList<Stat>();
|
||||
final String query = "select STAT_CODE, STAT_DATA from STATS where PLAYER_ID = " + playerId;
|
||||
execute(new Operation<Object>() {
|
||||
public Object invoke (Connection conn, DatabaseLiaison liaison)
|
||||
throws SQLException, PersistenceException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
try {
|
||||
ResultSet rs = stmt.executeQuery(query);
|
||||
while (rs.next()) {
|
||||
Stat stat = decodeStat(
|
||||
rs.getInt(1), (byte[])rs.getObject(2));
|
||||
if (stat != null) {
|
||||
stats.add(stat);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
JDBCUtil.close(stmt);
|
||||
}
|
||||
return null;
|
||||
ArrayList<Stat> stats = new ArrayList<Stat>();
|
||||
Where where = new Where(StatRecord.PLAYER_ID_C, playerId);
|
||||
for (StatRecord record : findAll(StatRecord.class, where)) {
|
||||
Stat stat = decodeStat(record.statCode, record.statData);
|
||||
if (stat != null) {
|
||||
stats.add(stat);
|
||||
}
|
||||
});
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all stats associated with the specified player.
|
||||
*/
|
||||
public void deleteStats (int playerId)
|
||||
public void deleteStats (final int playerId)
|
||||
throws PersistenceException
|
||||
{
|
||||
update("delete from STATS where PLAYER_ID = " + playerId);
|
||||
CacheInvalidator invalidator = new CacheInvalidator() {
|
||||
public void invalidate (PersistenceContext ctx) {
|
||||
ctx.cacheTraverse(StatRecord.class.getName(), new CacheEvictionFilter<StatRecord>() {
|
||||
public boolean testForEviction (Serializable key, StatRecord record) {
|
||||
return record != null && record.playerId == playerId;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
deleteAll(StatRecord.class, new Where(StatRecord.PLAYER_ID_C, playerId), invalidator);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes out any of the stats in the supplied array that have been modified since they were
|
||||
* first loaded. Exceptions that occur while writing the stats will be caught and logged.
|
||||
@@ -222,11 +232,7 @@ public class StatRepository extends SimpleRepository
|
||||
protected void updateStat (int playerId, final Stat stat)
|
||||
throws PersistenceException
|
||||
{
|
||||
final String uquery = "update STATS set STAT_DATA = ?" +
|
||||
" where PLAYER_ID = " + playerId + " and STAT_CODE = " + stat.getCode();
|
||||
final String iquery = "insert into STATS (PLAYER_ID, STAT_CODE, " +
|
||||
"STAT_DATA) values (" + playerId + ", " + stat.getCode() + ", ?)";
|
||||
final ByteArrayOutInputStream out = new ByteArrayOutInputStream();
|
||||
ByteArrayOutInputStream out = new ByteArrayOutInputStream();
|
||||
try {
|
||||
stat.persistTo(new ObjectOutputStream(out), this);
|
||||
} catch (IOException ioe) {
|
||||
@@ -234,111 +240,71 @@ public class StatRepository extends SimpleRepository
|
||||
throw new PersistenceException(errmsg, ioe);
|
||||
}
|
||||
|
||||
// now update (or insert) the flattened data into the database
|
||||
executeUpdate(new Operation<Object>() {
|
||||
public Object invoke (Connection conn, DatabaseLiaison liaison)
|
||||
throws SQLException, PersistenceException
|
||||
{
|
||||
PreparedStatement stmt = conn.prepareStatement(uquery);
|
||||
try {
|
||||
stmt.setBinaryStream(1, out.getInputStream(), out.size());
|
||||
if (stmt.executeUpdate() == 0) {
|
||||
JDBCUtil.close(stmt);
|
||||
stmt = conn.prepareStatement(iquery);
|
||||
stmt.setBinaryStream(1, out.getInputStream(), out.size());
|
||||
JDBCUtil.checkedUpdate(stmt, 1);
|
||||
}
|
||||
return null;
|
||||
} finally {
|
||||
JDBCUtil.close(stmt);
|
||||
}
|
||||
}
|
||||
});
|
||||
store(new StatRecord(playerId, stat.getCode(), out.toByteArray()));
|
||||
}
|
||||
|
||||
@Computed @Entity
|
||||
protected static class MaxStatCodeRecord extends PersistentRecord {
|
||||
int maxCode;
|
||||
};
|
||||
|
||||
/** Helper function for {@link #getStringCode}. */
|
||||
protected Integer assignStringCode (final Stat.Type type, final String value)
|
||||
throws PersistenceException
|
||||
{
|
||||
return executeUpdate(new Operation<Integer>() {
|
||||
public Integer invoke (Connection conn, DatabaseLiaison liaison)
|
||||
throws SQLException, PersistenceException
|
||||
{
|
||||
for (int ii = 0; ii < 10; ii++) {
|
||||
try {
|
||||
int code = getNextCode(conn, type);
|
||||
// DEBUG: uncomment this to test code collision
|
||||
// if (ii == 0 && code > 0) {
|
||||
// code = code-1;
|
||||
// }
|
||||
insertStringCode(conn, type, value, code);
|
||||
return code;
|
||||
for (int ii = 0; ii < 10; ii++) {
|
||||
MaxStatCodeRecord maxRecord = load(
|
||||
MaxStatCodeRecord.class,
|
||||
new FromOverride(StringCodeRecord.class),
|
||||
new FieldOverride("maxCode", new FunctionExp("MAX", StringCodeRecord.CODE_C)),
|
||||
new Where(StringCodeRecord.STAT_CODE_C, type.code()));
|
||||
|
||||
} catch (SQLException sqe) {
|
||||
// if this is not a duplicate row exception, something is booched and we
|
||||
// just fail
|
||||
if (!liaison.isDuplicateRowException(sqe)) {
|
||||
throw sqe;
|
||||
}
|
||||
int code = maxRecord != null ? maxRecord.maxCode + 1 : 1;
|
||||
|
||||
// if it is a duplicate row exception, possibly someone inserted our value
|
||||
// before we could, in which case we can just look up the new mapping
|
||||
int code = getCurrentCode(conn, type, value);
|
||||
if (code != -1) {
|
||||
log.info("Value collision assigning string code [type=" + type +
|
||||
", value=" + value + "].");
|
||||
return code;
|
||||
}
|
||||
// DEBUG: uncomment this to test code collision
|
||||
// if (ii == 0 && code > 0) {
|
||||
// code = code-1;
|
||||
// }
|
||||
|
||||
try {
|
||||
insert(new StringCodeRecord(type.code(), value, code));
|
||||
return code;
|
||||
|
||||
// otherwise someone used the code we were trying to use and we just need
|
||||
// to loop around and get the next highest code
|
||||
log.info("Code collision assigning string code [type=" + type +
|
||||
", value=" + value + "].");
|
||||
}
|
||||
} catch (PersistenceException pe) {
|
||||
// if this is not a duplicate row exception, something is booched and we
|
||||
// just fail
|
||||
|
||||
// if (!liaison.isDuplicateRowException(sqe)) {
|
||||
// throw sqe;
|
||||
// }
|
||||
|
||||
// if it is a duplicate row exception, possibly someone inserted our value
|
||||
// before we could, in which case we can just look up the new mapping
|
||||
StringCodeRecord record = load(
|
||||
StringCodeRecord.class,
|
||||
new Where(StringCodeRecord.STAT_CODE_C, type.code(),
|
||||
StringCodeRecord.VALUE_C, value));
|
||||
if (record != null) {
|
||||
log.info("Value collision assigning string code [type=" + type +
|
||||
", value=" + value + "].");
|
||||
return code;
|
||||
}
|
||||
throw new SQLException("Unable to assign code after 10 attempts " +
|
||||
"[type=" + type + ", value=" + value + "]");
|
||||
|
||||
// otherwise someone used the code we were trying to use and we just need
|
||||
// to loop around and get the next highest code
|
||||
log.info("Code collision assigning string code [type=" + type +
|
||||
", value=" + value + "].");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Helper function for {@link #assignStringCode}. */
|
||||
protected int getNextCode (Connection conn, Stat.Type type)
|
||||
throws SQLException
|
||||
{
|
||||
return getCode(conn, "select MAX(CODE)+1 from STRING_CODES where STAT_CODE = " +
|
||||
type.code());
|
||||
}
|
||||
|
||||
/** Helper function for {@link #assignStringCode}. */
|
||||
protected int getCurrentCode (Connection conn, Stat.Type type, String value)
|
||||
throws SQLException
|
||||
{
|
||||
return getCode(conn, "select CODE from STRING_CODES where STAT_CODE = " + type.code() +
|
||||
" and VALUE = " + JDBCUtil.escape(value));
|
||||
}
|
||||
|
||||
/** Helper function for {@link #getNextCode} and {@link #getCurrentCode}. */
|
||||
protected int getCode (Connection conn, String query)
|
||||
throws SQLException
|
||||
{
|
||||
int code = -1;
|
||||
Statement stmt = conn.createStatement();
|
||||
try {
|
||||
ResultSet rs = stmt.executeQuery(query);
|
||||
while (rs.next()) {
|
||||
code = rs.getInt(1);
|
||||
}
|
||||
} finally {
|
||||
JDBCUtil.close(stmt);
|
||||
}
|
||||
return code;
|
||||
throw new PersistenceException(
|
||||
"Unable to assign code after 10 attempts [type=" + type + ", value=" + value + "]");
|
||||
}
|
||||
|
||||
/** Helper function for {@link #assignStringCode}. */
|
||||
protected void insertStringCode (Connection conn, Stat.Type type, String value, int code)
|
||||
throws SQLException
|
||||
{
|
||||
|
||||
String query = "insert into STRING_CODES (STAT_CODE, VALUE, CODE) values(" + type.code() +
|
||||
", " + JDBCUtil.escape(value) + ", " + code + ")";
|
||||
Statement stmt = conn.createStatement();
|
||||
@@ -358,24 +324,16 @@ public class StatRepository extends SimpleRepository
|
||||
protected void loadStringCodes (Stat.Type type)
|
||||
throws PersistenceException
|
||||
{
|
||||
final String query = "select STAT_CODE, VALUE, CODE from STRING_CODES " +
|
||||
((type == null) ? "" : (" where STAT_CODE = " + type.code()));
|
||||
execute(new Operation<Object>() {
|
||||
public Object invoke (Connection conn, DatabaseLiaison liaison)
|
||||
throws SQLException, PersistenceException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
try {
|
||||
ResultSet rs = stmt.executeQuery(query);
|
||||
while (rs.next()) {
|
||||
mapStringCode(Stat.getType(rs.getInt(1)), rs.getString(2), rs.getInt(3));
|
||||
}
|
||||
} finally {
|
||||
JDBCUtil.close(stmt);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
QueryClause[] clauses;
|
||||
if (type != null) {
|
||||
clauses = new QueryClause[] { new Where(StringCodeRecord.STAT_CODE_C, type.code()) };
|
||||
} else {
|
||||
clauses = new QueryClause[0];
|
||||
}
|
||||
|
||||
for (StringCodeRecord record : findAll(StringCodeRecord.class, clauses)) {
|
||||
mapStringCode(Stat.getType(record.statCode), record.value, record.code);
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper function used at repository startup. */
|
||||
@@ -393,25 +351,11 @@ public class StatRepository extends SimpleRepository
|
||||
rmap.put(code, value);
|
||||
}
|
||||
|
||||
@Override // documentation inherited
|
||||
protected void migrateSchema (Connection conn, DatabaseLiaison liaison)
|
||||
throws SQLException, PersistenceException
|
||||
@Override // from DepotRepository
|
||||
protected void getManagedRecords (Set<Class<? extends PersistentRecord>> classes)
|
||||
{
|
||||
JDBCUtil.createTableIfMissing(conn, "STATS", new String[] {
|
||||
"PLAYER_ID INTEGER NOT NULL",
|
||||
"STAT_CODE INTEGER NOT NULL",
|
||||
"STAT_DATA BLOB NOT NULL",
|
||||
"KEY (PLAYER_ID)",
|
||||
"KEY (STAT_CODE)",
|
||||
}, "");
|
||||
|
||||
JDBCUtil.createTableIfMissing(conn, "STRING_CODES", new String[] {
|
||||
"STAT_CODE INTEGER NOT NULL",
|
||||
"VALUE VARCHAR(255) NOT NULL",
|
||||
"CODE INTEGER NOT NULL",
|
||||
"UNIQUE (STAT_CODE, VALUE)",
|
||||
"UNIQUE (STAT_CODE, CODE)",
|
||||
}, "");
|
||||
classes.add(StatRecord.class);
|
||||
classes.add(StringCodeRecord.class);
|
||||
}
|
||||
|
||||
protected HashMap<Stat.Type,HashMap<String,Integer>> _stringToCode =
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// $Id: PuzzleManagerDelegate.java 209 2007-02-24 00:37:33Z mdb $
|
||||
//
|
||||
// Vilya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/vilya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.stats.server.persist;
|
||||
|
||||
import com.samskivert.jdbc.depot.Key;
|
||||
import com.samskivert.jdbc.depot.PersistentRecord;
|
||||
import com.samskivert.jdbc.depot.annotation.Column;
|
||||
import com.samskivert.jdbc.depot.annotation.Entity;
|
||||
import com.samskivert.jdbc.depot.annotation.Id;
|
||||
import com.samskivert.jdbc.depot.annotation.Table;
|
||||
import com.samskivert.jdbc.depot.annotation.UniqueConstraint;
|
||||
import com.samskivert.jdbc.depot.expression.ColumnExp;
|
||||
|
||||
@Entity(name="STRING_CODES")
|
||||
@Table(uniqueConstraints={
|
||||
@UniqueConstraint(columnNames={StringCodeRecord.STAT_CODE, StringCodeRecord.VALUE}),
|
||||
@UniqueConstraint(columnNames={StringCodeRecord.STAT_CODE, StringCodeRecord.CODE})})
|
||||
public class StringCodeRecord extends PersistentRecord
|
||||
{
|
||||
// AUTO-GENERATED: FIELDS START
|
||||
/** The column identifier for the {@link #statCode} field. */
|
||||
public static final String STAT_CODE = "statCode";
|
||||
|
||||
/** The qualified column identifier for the {@link #statCode} field. */
|
||||
public static final ColumnExp STAT_CODE_C =
|
||||
new ColumnExp(StringCodeRecord.class, STAT_CODE);
|
||||
|
||||
/** The column identifier for the {@link #value} field. */
|
||||
public static final String VALUE = "value";
|
||||
|
||||
/** The qualified column identifier for the {@link #value} field. */
|
||||
public static final ColumnExp VALUE_C =
|
||||
new ColumnExp(StringCodeRecord.class, VALUE);
|
||||
|
||||
/** The column identifier for the {@link #code} field. */
|
||||
public static final String CODE = "code";
|
||||
|
||||
/** The qualified column identifier for the {@link #code} field. */
|
||||
public static final ColumnExp CODE_C =
|
||||
new ColumnExp(StringCodeRecord.class, CODE);
|
||||
// AUTO-GENERATED: FIELDS END
|
||||
|
||||
public static final int SCHEMA_VERSION = 2;
|
||||
|
||||
/** The code of the stat. */
|
||||
@Id
|
||||
@Column(name="STAT_CODE")
|
||||
public int statCode;
|
||||
|
||||
@Id
|
||||
@Column(name="VALUE")
|
||||
public String value;
|
||||
|
||||
@Id
|
||||
@Column(name="CODE")
|
||||
public int code;
|
||||
|
||||
/**
|
||||
* An empty constructor for unmarshalling.
|
||||
*/
|
||||
public StringCodeRecord ()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that populates all our fields.
|
||||
*/
|
||||
public StringCodeRecord (int statCode, String value, int code)
|
||||
{
|
||||
super();
|
||||
this.statCode = statCode;
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED: METHODS START
|
||||
/**
|
||||
* Create and return a primary {@link Key} to identify a {@link #StringCodeRecord}
|
||||
* with the supplied key values.
|
||||
*/
|
||||
public static Key<StringCodeRecord> getKey (int statCode, String value, int code)
|
||||
{
|
||||
return new Key<StringCodeRecord>(
|
||||
StringCodeRecord.class,
|
||||
new String[] { STAT_CODE, VALUE, CODE },
|
||||
new Comparable[] { statCode, value, code });
|
||||
}
|
||||
// AUTO-GENERATED: METHODS END
|
||||
}
|
||||
Reference in New Issue
Block a user