Files
ooo-user/src/main/java/com/threerings/user/ReferralRepository.java
T
2011-10-05 09:37:10 -07:00

170 lines
5.1 KiB
Java

//
// $Id$
package com.threerings.user;
import java.sql.Connection;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Statement;
import com.samskivert.io.PersistenceException;
import com.samskivert.jdbc.ConnectionProvider;
import com.samskivert.jdbc.JDBCUtil;
import com.samskivert.jdbc.DatabaseLiaison;
import com.samskivert.jdbc.JORARepository;
import com.samskivert.jdbc.jora.Table;
import static com.threerings.user.Log.log;
/**
* Tracks the data needed for our personal referral system whereby one
* user sends a referral link (or email) to their friend and we track the
* original referring user if their referred friend actually registers
* within some reasonable time frame (like a couple of weeks).
*/
public class ReferralRepository extends JORARepository
{
/**
* The database identifier used when establishing a database
* connection. This value being <code>referraldb</code>.
*/
public static final String REFERRAL_DB_IDENT = "referraldb";
/**
* Creates the repository and prepares it for operation.
*
* @param provider the database connection provider.
*/
public ReferralRepository (ConnectionProvider provider)
throws PersistenceException
{
super(provider, REFERRAL_DB_IDENT);
// figure out whether or not the referral system is in use
execute(new Operation<Void>() {
public Void invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException
{
_active = JDBCUtil.tableExists(conn, "REFERRAL");
if (!_active) {
log.info("No referral table. Disabling.");
}
return null;
}
});
}
/**
* Records a new referral record in the system and returns the unique
* identifier for said record.
*/
public int recordReferral (int referrerId, String data)
throws PersistenceException
{
if (!_active) {
throw new PersistenceException("Referral repository is not available.");
}
final ReferralRecord record = new ReferralRecord();
record.recorded = new Date(System.currentTimeMillis());
record.referrerId = referrerId;
record.data = data;
record.referralId = insert(_rtable, record);
checkPurge();
return record.referralId;
}
/**
* Looks up a referral record with the specified id, returning null if
* no matching record could be found.
*/
public ReferralRecord lookupReferral (int referralId)
throws PersistenceException
{
return lookupReferralBy("where REFERRAL_ID = " + referralId);
}
/**
* Looks up a referral record with the specified referring user id,
* returning null if no matching record could be found.
*/
public ReferralRecord lookupReferrer (int referrerId)
throws PersistenceException
{
return lookupReferralBy("where REFERRER_ID = " + referrerId);
}
/** Looks up a referral record matching the specified query. */
protected ReferralRecord lookupReferralBy (final String query)
throws PersistenceException
{
if (!_active) {
return null;
}
ReferralRecord record = load(_rtable, query);
checkPurge();
return record;
}
/**
* Used to periodically purge old referral records from the
* repository.
*/
protected void checkPurge ()
{
long now = System.currentTimeMillis();
if (now - _lastPurge > PURGE_INTERVAL) {
_lastPurge = now;
try {
purgeStaleReferrals();
} catch (PersistenceException pe) {
log.warning("Error purging referrals: " + pe);
}
}
}
/**
* Purges stale referral records from the repository.
*/
protected void purgeStaleReferrals ()
throws PersistenceException
{
executeUpdate(new Operation<Void>() {
public Void invoke (Connection conn, DatabaseLiaison liaison)
throws SQLException, PersistenceException
{
String pquery = "delete from REFERRAL " +
"where DATE_SUB(NOW(), INTERVAL 1 MONTH) > RECORDED;";
Statement stmt = conn.createStatement();
try {
stmt.executeUpdate(pquery);
} finally {
JDBCUtil.close(stmt);
}
return null;
}
});
}
@Override
protected void createTables ()
{
_rtable = new Table<ReferralRecord>(ReferralRecord.class, "REFERRAL", "REFERRAL_ID", true);
}
/** The table used to new billing actions that have taken place. */
protected Table<ReferralRecord> _rtable;
/** If we don't detect our tables, we deactivate ourselves. */
protected boolean _active;
/** The last time we purged the repository of stale records. */
protected long _lastPurge;
/** We purge the repository every three hours of stale records. */
protected static final long PURGE_INTERVAL = 3 * 60 * 60 * 1000L;
}