package edu.umd.rhsmith.diads.meater.modules.tweater.queries.legacy;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;
import javax.sql.DataSource;
import twitter4j.GeoLocation;
import edu.umd.rhsmith.diads.meater.core.app.MEaterConfigurationException;
import edu.umd.rhsmith.diads.meater.modules.tweater.queries.QueryFollow;
import edu.umd.rhsmith.diads.meater.modules.tweater.queries.QueryItemTime;
import edu.umd.rhsmith.diads.meater.modules.tweater.queries.QueryLocation;
import edu.umd.rhsmith.diads.meater.modules.tweater.queries.QueryPhrase;
import edu.umd.rhsmith.diads.meater.modules.tweater.queries.QueryTrack;
import edu.umd.rhsmith.diads.meater.util.NumberSet;
import edu.umd.rhsmith.diads.meater.util.Util;
/**
* Reads query items from a MySQL database.
*
* @author dmonner
*/
public class MySqlQuerySource extends QuerySource {
private final String dbName;
/**
* The MySQL connection pool
*/
private DataSource ds;
/**
* The SQL WHERE string that specifies query groups
*/
private final String where;
/**
* The maximum number of tries to try a transaction before giving up
*/
private final int maxtries = 5;
public MySqlQuerySource(MySqlQuerySourceInitializer init)
throws MEaterConfigurationException {
super(init);
this.dbName = init.getDbName();
final String querygroups = init.getQueryGroups();
if (querygroups != null && !querygroups.trim().isEmpty()) {
where = " WHERE "
+ new NumberSet(querygroups).toSQL("query_group_no");
} else {
where = "";
}
}
@Override
protected void doInitRoutine() throws MEaterConfigurationException {
super.doInitRoutine();
this.ds = this.getComponentManager().getMain().getSqlManager()
.getDataSource(dbName);
if (this.ds == null) {
throw new MEaterConfigurationException(this.messageString(
MSG_ERR_NOSOURCE_FMT, dbName));
}
}
/*
* (non-Javadoc)
*
* @see edu.umd.cs.dmonner.tweater.QueryBuilder#update()
*/
@Override
public List<QueryItemTime> getQueriesFromSource() {
logFine(MSG_UPDATE_BEGIN);
final List<QueryItemTime> all = new LinkedList<QueryItemTime>();
boolean querySucceeded = false;
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
int tries = 0;
try {
// build a new tree of all query items
while (conn == null && tries++ < maxtries) {
conn = ds.getConnection();
}
if (conn == null) {
logWarning(MSG_ERR_COULDNT_CONNECT);
return null;
}
stmt = conn.createStatement();
// get the track queries
rs = stmt
.executeQuery("SELECT query_group_no, query_track_no, query_track_string, query_start_time, query_end_time "
+ "FROM query_group INNER JOIN query_track USING (query_group_no)"
+ where + ";");
while (rs.next()) {
all.add(new QueryItemTime(new QueryTrack(rs
.getInt("query_track_no"), rs
.getString("query_track_string")), rs
.getLong("query_start_time"), rs
.getLong("query_end_time")));
}
// get the phrase queries
rs = stmt
.executeQuery("SELECT query_group_no, query_phrase_no, query_phrase_string, query_start_time, query_end_time "
+ "FROM query_group INNER JOIN query_phrase USING (query_group_no)"
+ where + ";");
while (rs.next()) {
all.add(new QueryItemTime(new QueryPhrase(rs
.getInt("query_group_no"), rs
.getString("query_phrase_string")), rs
.getLong("query_start_time"), rs
.getLong("query_end_time")));
}
// get the follow queries
rs = stmt
.executeQuery("SELECT query_group_no, query_follow_no, query_user_id, query_start_time, query_end_time "
+ "FROM query_group INNER JOIN query_follow USING (query_group_no)"
+ where + ";");
while (rs.next()) {
all.add(new QueryItemTime(
new QueryFollow(rs.getInt("query_follow_no"), rs
.getLong("query_user_id")), rs
.getLong("query_start_time"), rs
.getLong("query_end_time")));
}
// get the location queries
rs = stmt
.executeQuery("SELECT query_group_no, query_location_no, "
+ "query_location_longSW, query_location_latSW, query_location_longNE, query_location_latNE, "
+ "query_start_time, query_end_time "
+ "FROM query_group INNER JOIN query_location USING (query_group_no)"
+ where + ";");
while (rs.next()) {
double longSW = rs.getDouble("query_location_longSW"), latSW = rs
.getDouble("query_location_latSW"), longNE = rs
.getDouble("query_location_longNE"), latNE = rs
.getDouble("query_location_latNE");
GeoLocation pointSW = new GeoLocation(latSW, longSW);
GeoLocation pointNE = new GeoLocation(latNE, longNE);
QueryLocation ql = null;
try {
ql = new QueryLocation(rs.getInt("query_location_no"),
pointSW, pointNE);
} catch (IllegalArgumentException ex) {
logWarning("Unable to construct location query #"
+ rs.getInt("query_location_no") + ": "
+ ex.getMessage());
}
if (ql != null) {
all.add(new QueryItemTime(ql, rs
.getLong("query_start_time"), rs
.getLong("query_end_time")));
}
}
querySucceeded = true;
} catch (final SQLException ex) {
logSevere("SQLState: " + ex.getSQLState() + "\n" + //
"VendorError: " + ex.getErrorCode() + "\n" + //
Util.traceMessage(ex));
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (final SQLException ex) {
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (final SQLException ex) {
} finally {
try {
if (conn != null) {
conn.close();
}
} catch (final SQLException ex) {
}
}
}
}
if (querySucceeded) {
logFine(MSG_UPDATED);
return all;
} else {
logWarning(MSG_ERR_UPDATE_FAILED);
return null;
}
}
/*
* --------------------------------
* Messages
* --------------------------------
*/
private static final String MSG_UPDATED = "Completed MySQLQueryBuilder update.";
private static final String MSG_ERR_UPDATE_FAILED = "MySQLQueryBuilder update FAILED!";
private static final String MSG_UPDATE_BEGIN = "Beginning MySQLQueryBuilder update...";
private static final String MSG_ERR_NOSOURCE_FMT = "Couldn't get data source from manager with name '%s'";
private static final String MSG_ERR_COULDNT_CONNECT = "Unable to make connection to database";
}