Skip to content
Snippets Groups Projects
Commit b0ec7ee7 authored by millmanorama's avatar millmanorama
Browse files

fix more Postgres compatibility problems

parent f9d0ba0b
No related branches found
No related tags found
No related merge requests found
...@@ -93,7 +93,7 @@ public String csvAggFunction(String args) { ...@@ -93,7 +93,7 @@ public String csvAggFunction(String args) {
} }
public String csvAggFunction(String args, String seperator) { public String csvAggFunction(String args, String seperator) {
return csvFunction + "(" + args + ", '" + seperator + "')"; return csvFunction + "(Cast (" + args + " AS VARCHAR) , '" + seperator + "')";
} }
TimelineManager(SleuthkitCase tskCase) throws TskCoreException { TimelineManager(SleuthkitCase tskCase) throws TskCoreException {
...@@ -108,13 +108,13 @@ public Interval getSpanningInterval(Collection<Long> eventIDs) throws TskCoreExc ...@@ -108,13 +108,13 @@ public Interval getSpanningInterval(Collection<Long> eventIDs) throws TskCoreExc
if (eventIDs.isEmpty()) { if (eventIDs.isEmpty()) {
return null; return null;
} }
final String query = "SELECT Min(time), Max(time) FROM events WHERE event_id IN (" + StringUtils.joinAsStrings(eventIDs, ", ") + ")"; final String query = "SELECT Min(time) as minTime, Max(time) as maxTime FROM events WHERE event_id IN (" + StringUtils.joinAsStrings(eventIDs, ", ") + ")";
sleuthkitCase.acquireSingleUserCaseReadLock(); sleuthkitCase.acquireSingleUserCaseReadLock();
try (CaseDbConnection con = sleuthkitCase.getConnection(); try (CaseDbConnection con = sleuthkitCase.getConnection();
Statement stmt = con.createStatement(); Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);) { ResultSet rs = stmt.executeQuery(query);) {
while (rs.next()) { while (rs.next()) {
return new Interval(rs.getLong("Min(time)") * 1000, (rs.getLong("Max(time)") + 1) * 1000, DateTimeZone.UTC); // NON-NLS return new Interval(rs.getLong("minTime") * 1000, (rs.getLong("maxTime") + 1) * 1000, DateTimeZone.UTC); // NON-NLS
} }
} catch (SQLException ex) { } catch (SQLException ex) {
...@@ -1136,18 +1136,17 @@ public List<EventStripe> getEventStripes(ZoomParams params, DateTimeZone tz) thr ...@@ -1136,18 +1136,17 @@ public List<EventStripe> getEventStripes(ZoomParams params, DateTimeZone tz) thr
RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(timeRange, tz); RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(timeRange, tz);
//build dynamic parts of query //build dynamic parts of query
String strfTimeFormat = getStrfTimeFormat(rangeInfo.getPeriodSize());
String descriptionColumn = getDescriptionColumn(descriptionLOD); String descriptionColumn = getDescriptionColumn(descriptionLOD);
final boolean useSubTypes = typeZoomLevel.equals(EventTypeZoomLevel.SUB_TYPE); final boolean useSubTypes = typeZoomLevel.equals(EventTypeZoomLevel.SUB_TYPE);
String timeZone = tz.equals(DateTimeZone.getDefault()) ? ", 'localtime'" : ""; // NON-NLS String timeZone = tz.equals(DateTimeZone.getDefault()) ? ", 'localtime'" : ""; // NON-NLS
String typeColumn = typeColumnHelper(useSubTypes); String typeColumn = typeColumnHelper(useSubTypes);
//compose query string, the new-lines are only for nicer formatting if printing the entire query //compose query string, the new-lines are only for nicer formatting if printing the entire query
String query = "SELECT strftime('" + strfTimeFormat + "',time , 'unixepoch'" + timeZone + ") AS interval, " // NON-NLS String query = "SELECT " + formatTimeFunction(rangeInfo.getPeriodSize(), tz) + " AS interval, " // NON-NLS
+ csvFunction + "(events.event_id) as event_ids, " //NON-NLS + csvAggFunction("events.event_id") + " as event_ids, " //NON-NLS
+ csvFunction + "(CASE WHEN hash_hit = 1 THEN events.event_id ELSE NULL END) as hash_hits, " //NON-NLS + csvAggFunction("CASE WHEN hash_hit = 1 THEN events.event_id ELSE NULL END") + " as hash_hits, " //NON-NLS
+ csvFunction + "(CASE WHEN tagged = 1 THEN events.event_id ELSE NULL END) as taggeds, " //NON-NLS + csvAggFunction("CASE WHEN tagged = 1 THEN events.event_id ELSE NULL END") + " as taggeds, " //NON-NLS
+ " min(time), max(time), " + typeColumn + ", " + descriptionColumn // NON-NLS + " min(time) AS minTime, max(time) AS maxTime, " + typeColumn + ", " + descriptionColumn // NON-NLS
+ " FROM events" + useHashHitTablesHelper(filter) + useTagTablesHelper(filter) // NON-NLS + " FROM events" + useHashHitTablesHelper(filter) + useTagTablesHelper(filter) // NON-NLS
+ " WHERE time >= " + start + " AND time < " + end + " AND " + getSQLWhere(filter) // NON-NLS + " WHERE time >= " + start + " AND time < " + end + " AND " + getSQLWhere(filter) // NON-NLS
+ " GROUP BY interval, " + typeColumn + " , " + descriptionColumn // NON-NLS + " GROUP BY interval, " + typeColumn + " , " + descriptionColumn // NON-NLS
...@@ -1172,6 +1171,21 @@ public List<EventStripe> getEventStripes(ZoomParams params, DateTimeZone tz) thr ...@@ -1172,6 +1171,21 @@ public List<EventStripe> getEventStripes(ZoomParams params, DateTimeZone tz) thr
return mergeClustersToStripes(rangeInfo.getPeriodSize().getPeriod(), events); return mergeClustersToStripes(rangeInfo.getPeriodSize().getPeriod(), events);
} }
String formatTimeFunction(TimeUnits periodSize, DateTimeZone tz) {
switch (sleuthkitCase.getDatabaseType()) {
case SQLITE:
String strfTimeFormat = getStrfTimeFormat(periodSize);
String timeZone = tz.equals(DateTimeZone.getDefault()) ? ", 'localtime'" : ""; // NON-NLS
return "strftime('" + strfTimeFormat + "', time , 'unixepoch'" + timeZone + ")";
case POSTGRESQL:
String formatString = getPostgresTimeFormat(periodSize);
return "to_char(to_timestamp(time) AT TIME ZONE '" + tz.getID() + "', '" + formatString + "')";
default:
throw new UnsupportedOperationException("DbType " + sleuthkitCase.getDatabaseType() + " is not supported.");
}
}
/** /**
* map a single row in a ResultSet to an EventCluster * map a single row in a ResultSet to an EventCluster
* *
...@@ -1187,7 +1201,7 @@ public List<EventStripe> getEventStripes(ZoomParams params, DateTimeZone tz) thr ...@@ -1187,7 +1201,7 @@ public List<EventStripe> getEventStripes(ZoomParams params, DateTimeZone tz) thr
* @throws SQLException * @throws SQLException
*/ */
private EventCluster eventClusterHelper(ResultSet rs, boolean useSubTypes, DescriptionLoD descriptionLOD, TagsFilter filter, DateTimeZone tz) throws SQLException { private EventCluster eventClusterHelper(ResultSet rs, boolean useSubTypes, DescriptionLoD descriptionLOD, TagsFilter filter, DateTimeZone tz) throws SQLException {
Interval interval = new Interval(rs.getLong("min(time)") * 1000, rs.getLong("max(time)") * 1000, tz);// NON-NLS Interval interval = new Interval(rs.getLong("minTime") * 1000, rs.getLong("maxTime") * 1000, tz);// NON-NLS
String eventIDsString = rs.getString("event_ids");// NON-NLS String eventIDsString = rs.getString("event_ids");// NON-NLS
List<Long> eventIDs = unGroupConcat(eventIDsString, Long::valueOf); List<Long> eventIDs = unGroupConcat(eventIDsString, Long::valueOf);
String description = rs.getString(getDescriptionColumn(descriptionLOD)); String description = rs.getString(getDescriptionColumn(descriptionLOD));
...@@ -1289,7 +1303,8 @@ String useTagTablesHelper(RootFilter filter) { ...@@ -1289,7 +1303,8 @@ String useTagTablesHelper(RootFilter filter) {
/** /**
* take the result of a group_concat SQLite operation and split it into a * take the result of a group_concat SQLite operation and split it into a
* set of X using the mapper to to convert from string to X * set of X using the mapper to to convert from string to X If groupConcat
* is empty, null, or all whitespace, returns an empty list.
* *
* @param <X> the type of elements to return * @param <X> the type of elements to return
* @param groupConcat a string containing the group_concat result ( a comma * @param groupConcat a string containing the group_concat result ( a comma
...@@ -1300,7 +1315,11 @@ String useTagTablesHelper(RootFilter filter) { ...@@ -1300,7 +1315,11 @@ String useTagTablesHelper(RootFilter filter) {
* comma delimited string * comma delimited string
*/ */
<X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) { <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
List<X> result = new ArrayList<X>(); if (org.apache.commons.lang3.StringUtils.isBlank(groupConcat)) {
return Collections.emptyList();
}
List<X> result = new ArrayList<>();
String[] split = groupConcat.split(","); String[] split = groupConcat.split(",");
for (String s : split) { for (String s : split) {
result.add(mapper.apply(s)); result.add(mapper.apply(s));
...@@ -1529,6 +1548,24 @@ String getStrfTimeFormat(TimeUnits timeUnit) { ...@@ -1529,6 +1548,24 @@ String getStrfTimeFormat(TimeUnits timeUnit) {
} }
} }
String getPostgresTimeFormat(TimeUnits timeUnit) {
switch (timeUnit) {
case YEARS:
return "YYYY-01-01T00:00:00"; // NON-NLS
case MONTHS:
return "YYYY-MM-01T00:00:00"; // NON-NLS
case DAYS:
return "YYYY-MM-DDT00:00:00"; // NON-NLS
case HOURS:
return "YYYY-MM-DDTHH24:00:00"; // NON-NLS
case MINUTES:
return "YYYY-MM-DDTHH24:MI:00"; // NON-NLS
case SECONDS:
default: //seconds - should never happen
return "YYYY-MM-DDTHH24:MI:SS"; // NON-NLS
}
}
String getDescriptionColumn(DescriptionLoD lod) { String getDescriptionColumn(DescriptionLoD lod) {
switch (lod) { switch (lod) {
case FULL: case FULL:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment