package pt.ist.fenixframework.pstm;
import java.sql.Blob;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.joda.time.Partial;
import pt.ist.fenixframework.DomainObject;
public class ResultSetReader {
public static <T extends DomainObject> T readDomainObject(ResultSet rs, String columnName) throws SQLException {
long oid = rs.getLong(columnName);
return (T)((oid == 0) ? null : AbstractDomainObject.fromOID(oid));
}
public static <T extends Enum<T>> T readEnum(Class<T> enumClass, ResultSet rs, String columnName) throws SQLException {
String name = rs.getString(columnName);
return ((name == null) || name.equals("")) ? null : Enum.valueOf(enumClass, name);
}
public static boolean readboolean(ResultSet rs, String columnName) throws SQLException {
return rs.getBoolean(columnName);
}
public static byte readbyte(ResultSet rs, String columnName) throws SQLException {
return rs.getByte(columnName);
}
public static char readchar(ResultSet rs, String columnName) throws SQLException {
String txt = rs.getString(columnName);
if ((txt == null) || (txt.length() != 1)) {
throw new SQLException("Couldn't load a char for column " + columnName);
}
return txt.charAt(0);
}
public static short readshort(ResultSet rs, String columnName) throws SQLException {
return rs.getShort(columnName);
}
public static int readint(ResultSet rs, String columnName) throws SQLException {
return rs.getInt(columnName);
}
public static float readfloat(ResultSet rs, String columnName) throws SQLException {
return rs.getFloat(columnName);
}
public static long readlong(ResultSet rs, String columnName) throws SQLException {
return rs.getLong(columnName);
}
public static double readdouble(ResultSet rs, String columnName) throws SQLException {
return rs.getDouble(columnName);
}
public static Boolean readBoolean(ResultSet rs, String columnName) throws SQLException {
Boolean result = rs.getBoolean(columnName);
return (rs.wasNull() ? null : result);
}
public static Byte readByte(ResultSet rs, String columnName) throws SQLException {
Byte result = rs.getByte(columnName);
return (rs.wasNull() ? null : result);
}
public static Character readCharacter(ResultSet rs, String columnName) throws SQLException {
String txt = rs.getString(columnName);
if (txt == null) {
return null;
}
if (txt.length() != 1) {
throw new SQLException("Column " + columnName + " doesn't hold a single character");
}
return txt.charAt(0);
}
public static Short readShort(ResultSet rs, String columnName) throws SQLException {
Short result = rs.getShort(columnName);
return (rs.wasNull() ? null : result);
}
public static Integer readInteger(ResultSet rs, String columnName) throws SQLException {
Integer result = rs.getInt(columnName);
return (rs.wasNull() ? null : result);
}
public static Float readFloat(ResultSet rs, String columnName) throws SQLException {
Float result = rs.getFloat(columnName);
return (rs.wasNull() ? null : result);
}
public static Long readLong(ResultSet rs, String columnName) throws SQLException {
Long result = rs.getLong(columnName);
return (rs.wasNull() ? null : result);
}
public static Double readDouble(ResultSet rs, String columnName) throws SQLException {
Double result = rs.getDouble(columnName);
return (rs.wasNull() ? null : result);
}
public static String readString(ResultSet rs, String columnName) throws SQLException {
return rs.getString(columnName);
}
public static byte[] readbytearray(ResultSet rs, String columnName) throws SQLException {
Blob aBlob = rs.getBlob(columnName);
return (rs.wasNull() ? null : aBlob.getBytes(1L, (int) aBlob.length()));
}
public static DateTime readDateTime(ResultSet rs, String columnName) throws SQLException {
Timestamp tstamp = rs.getTimestamp(columnName);
return (rs.wasNull() ? null : new DateTime(tstamp.getTime()));
}
public static LocalDate readLocalDate(ResultSet rs, String columnName) throws SQLException {
/* Ideally, we would like to use an SQL DATE to store a LocalDate, but there is a bug in the mysql driver in the
* rs.getDate(...) method. The driver internally loses the timezone information and then always uses the default time
* zone. I.e., we would like to write something like:
*
* Date date = rs.getDate(columnName, new java.util.GregorianCalendar(java.util.TimeZone.getTimeZone("UTC")));
*
* Additionally, trying to solve the problem by changing the JVM's default timezone to match UTC is not acceptable.
*/
String dateAsString = rs.getString(columnName);
return (rs.wasNull() ? null : LocalDateExternalization.localDateFromString(dateAsString));
}
public static LocalTime readLocalTime(ResultSet rs, String columnName) throws SQLException {
// Get the time without specifying a Calendar for the time
// zone, because OJB does not use it when binding the
// preparedStatement also. So, we must get the java.sql.Time
// in the default time zone.
//
// Moreover, if later we decide to change this, we must
// investigate the various options for the MySQL driver,
// because by default I think that it does not behave as
// expected by the JDBC specification. Check the options
// "noTimezoneConversionForTimeType", "useTimezone",
// "useGmtMillisForDatetimes",
// "useJDBCCompliantTimezoneShift", "useLegacyDatetimeCode",
// and "useSSPSCompatibleTimezoneShift" (at least...).
Time time = rs.getTime(columnName);
// Construct the LocalTime with hours, minutes, and seconds,
// for symmetry with the ToSqlConverter code (see the comment
// there, also).
return (rs.wasNull() ? null : new LocalTime(time.getHours(), time.getMinutes(), time.getSeconds()));
}
public static Partial readPartial(ResultSet rs, String columnName) throws SQLException {
String partialAsString = rs.getString(columnName);
return (partialAsString == null) ? null : PartialExternalization.partialFromString(partialAsString);
}
// public static Period readPeriod(ResultSet rs, String columnName) throws SQLException {
// }
}