Skip to content
Snippets Groups Projects
Unverified Commit 1d238bd8 authored by Richard Cordovano's avatar Richard Cordovano Committed by GitHub
Browse files

Merge pull request #2136 from APriestman/7251_fixDbUpgrade

7251 Fix issue with the order of database upgrades and loading artifact ta…
parents d504cfb5 990b7248
No related branches found
No related tags found
No related merge requests found
...@@ -368,13 +368,12 @@ private void init() throws Exception { ...@@ -368,13 +368,12 @@ private void init() throws Exception {
typeNameToAttributeTypeMap = new ConcurrentHashMap<>(); typeNameToAttributeTypeMap = new ConcurrentHashMap<>();
   
/* /*
* The following methods need to be called before updateDatabaseSchema * The database schema must be updated before loading blackboard artifact/attribute types
* due to the way that updateFromSchema2toSchema3 was implemented.
*/ */
updateDatabaseSchema(null);
initBlackboardArtifactTypes(); initBlackboardArtifactTypes();
initBlackboardAttributeTypes(); initBlackboardAttributeTypes();
initNextArtifactId(); initNextArtifactId();
updateDatabaseSchema(null);
   
try (CaseDbConnection connection = connections.getConnection()) { try (CaseDbConnection connection = connections.getConnection()) {
initIngestModuleTypes(connection); initIngestModuleTypes(connection);
...@@ -1072,11 +1071,13 @@ private CaseDbSchemaVersionNumber updateFromSchema2toSchema3(CaseDbSchemaVersion ...@@ -1072,11 +1071,13 @@ private CaseDbSchemaVersionNumber updateFromSchema2toSchema3(CaseDbSchemaVersion
return schemaVersion; return schemaVersion;
} }
Statement statement = null; Statement statement = null;
Statement statement2 = null;
Statement updateStatement = null; Statement updateStatement = null;
ResultSet resultSet = null; ResultSet resultSet = null;
acquireSingleUserCaseWriteLock(); acquireSingleUserCaseWriteLock();
try { try {
statement = connection.createStatement(); statement = connection.createStatement();
statement2 = connection.createStatement();
   
// Add new tables for tags. // Add new tables for tags.
statement.execute("CREATE TABLE tag_names (tag_name_id INTEGER PRIMARY KEY, display_name TEXT UNIQUE, description TEXT NOT NULL, color TEXT NOT NULL)"); //NON-NLS statement.execute("CREATE TABLE tag_names (tag_name_id INTEGER PRIMARY KEY, display_name TEXT UNIQUE, description TEXT NOT NULL, color TEXT NOT NULL)"); //NON-NLS
...@@ -1121,61 +1122,105 @@ private CaseDbSchemaVersionNumber updateFromSchema2toSchema3(CaseDbSchemaVersion ...@@ -1121,61 +1122,105 @@ private CaseDbSchemaVersionNumber updateFromSchema2toSchema3(CaseDbSchemaVersion
+ " WHERE blackboard_attributes.artifact_id = " + artifactId + ";"); //NON-NLS + " WHERE blackboard_attributes.artifact_id = " + artifactId + ";"); //NON-NLS
} }
resultSet.close(); resultSet.close();
resultSet = null;
   
// Convert existing tag artifact and attribute rows to rows in the new tags tables. // Convert existing tag artifact and attribute rows to rows in the new tags tables.
// TODO: This code depends on prepared statements that could evolve with Map<String, Long> tagNames = new HashMap<>();
// time, breaking this upgrade. The code that follows should be rewritten long tagNameCounter = 1;
// to do everything with SQL specific to case database schema version 2.
HashMap<String, TagName> tagNames = new HashMap<String, TagName>(); // Convert file tags.
for (BlackboardArtifact artifact : getBlackboardArtifacts(ARTIFACT_TYPE.TSK_TAG_FILE)) { // We need data from the TSK_TAG_NAME and TSK_COMMENT attributes, and need the file size from the tsk_files table.
Content content = getContentById(artifact.getObjectID()); resultSet = statement.executeQuery("SELECT * FROM \n" +
String name = ""; //NON-NLS "(SELECT blackboard_artifacts.obj_id AS objId, blackboard_attributes.artifact_id AS artifactId, blackboard_attributes.value_text AS name\n" +
String comment = ""; //NON-NLS "FROM blackboard_artifacts INNER JOIN blackboard_attributes \n" +
ArrayList<BlackboardAttribute> attributes = getBlackboardAttributes(artifact); "ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id \n" +
for (BlackboardAttribute attribute : attributes) { "WHERE blackboard_artifacts.artifact_type_id = " +
if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()) { BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID() +
name = attribute.getValueString(); " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()
} else if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()) { + ") AS tagNames \n" +
comment = attribute.getValueString(); "INNER JOIN \n" +
} "(SELECT tsk_files.obj_id as objId2, tsk_files.size AS fileSize \n" +
"FROM blackboard_artifacts INNER JOIN tsk_files \n" +
"ON blackboard_artifacts.obj_id = tsk_files.obj_id) AS fileData \n" +
"ON tagNames.objId = fileData.objId2 \n" +
"LEFT JOIN \n" +
"(SELECT value_text AS comment, artifact_id AS tagArtifactId FROM blackboard_attributes WHERE attribute_type_id = " +
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID() + ") AS tagComments \n" +
"ON tagNames.artifactId = tagComments.tagArtifactId");
while (resultSet.next()) {
long objId = resultSet.getLong("objId");
long fileSize = resultSet.getLong("fileSize");
String tagName = resultSet.getString("name");
String tagComment = resultSet.getString("comment");
if (tagComment == null) {
tagComment = "";
} }
if (!name.isEmpty()) {
TagName tagName; if (tagName != null && ! tagName.isEmpty()) {
if (tagNames.containsKey(name)) { // Get the index for the tag name, adding it to the database if needed.
tagName = tagNames.get(name); long tagNameIndex;
if (tagNames.containsKey(tagName)) {
tagNameIndex = tagNames.get(tagName);
} else { } else {
tagName = addTagName(name, "", TagName.HTML_COLOR.NONE); //NON-NLS statement2.execute("INSERT INTO tag_names (display_name, description, color) " +
tagNames.put(name, tagName); "VALUES(\"" + tagName + "\", \"\", \"None\")");
tagNames.put(tagName, tagNameCounter);
tagNameIndex = tagNameCounter;
tagNameCounter++;
} }
addContentTag(content, tagName, comment, 0, content.getSize() - 1);
statement2.execute("INSERT INTO content_tags (obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset) " +
"VALUES(" + objId + ", " + tagNameIndex + ", \"" + tagComment + "\", 0, " + fileSize + ")");
} }
} }
for (BlackboardArtifact artifact : getBlackboardArtifacts(ARTIFACT_TYPE.TSK_TAG_ARTIFACT)) { resultSet.close();
long taggedArtifactId = -1;
String name = ""; //NON-NLS // Convert artifact tags.
String comment = ""; //NON-NLS // We need data from the TSK_TAG_NAME, TSK_TAGGED_ARTIFACT, and TSK_COMMENT attributes.
ArrayList<BlackboardAttribute> attributes = getBlackboardAttributes(artifact); resultSet = statement.executeQuery("SELECT * FROM \n" +
for (BlackboardAttribute attribute : attributes) { "(SELECT blackboard_artifacts.obj_id AS objId, blackboard_attributes.artifact_id AS artifactId, " +
if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()) { "blackboard_attributes.value_text AS name\n" +
name = attribute.getValueString(); "FROM blackboard_artifacts INNER JOIN blackboard_attributes \n" +
} else if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()) { "ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id \n" +
comment = attribute.getValueString(); "WHERE blackboard_artifacts.artifact_type_id = " +
} else if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID()) { BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID() +
taggedArtifactId = attribute.getValueLong(); " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()
} + ") AS tagNames \n" +
"INNER JOIN \n" +
"(SELECT value_int64 AS taggedArtifactId, artifact_id AS associatedArtifactId FROM blackboard_attributes WHERE attribute_type_id = " +
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID() + ") AS tagArtifacts \n" +
"ON tagNames.artifactId = tagArtifacts.associatedArtifactId \n" +
"LEFT JOIN \n" +
"(SELECT value_text AS comment, artifact_id AS commentArtifactId FROM blackboard_attributes WHERE attribute_type_id = " +
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID() + ") AS tagComments \n" +
"ON tagNames.artifactId = tagComments.commentArtifactId");
while (resultSet.next()) {
long artifactId = resultSet.getLong("taggedArtifactId");
String tagName = resultSet.getString("name");
String tagComment = resultSet.getString("comment");
if (tagComment == null) {
tagComment = "";
} }
if (taggedArtifactId != -1 && !name.isEmpty()) { if (tagName != null && ! tagName.isEmpty()) {
TagName tagName; // Get the index for the tag name, adding it to the database if needed.
if (tagNames.containsKey(name)) { long tagNameIndex;
tagName = tagNames.get(name); if (tagNames.containsKey(tagName)) {
tagNameIndex = tagNames.get(tagName);
} else { } else {
tagName = addTagName(name, "", TagName.HTML_COLOR.NONE); //NON-NLS statement2.execute("INSERT INTO tag_names (display_name, description, color) " +
tagNames.put(name, tagName); "VALUES(\"" + tagName + "\", \"\", \"None\")");
tagNames.put(tagName, tagNameCounter);
tagNameIndex = tagNameCounter;
tagNameCounter++;
} }
addBlackboardArtifactTag(getBlackboardArtifact(taggedArtifactId), tagName, comment);
statement2.execute("INSERT INTO blackboard_artifact_tags (artifact_id, tag_name_id, comment) " +
"VALUES(" + artifactId + ", " + tagNameIndex + ", \"" + tagComment + "\")");
} }
} }
resultSet.close();
statement.execute( statement.execute(
"DELETE FROM blackboard_attributes WHERE artifact_id IN " //NON-NLS "DELETE FROM blackboard_attributes WHERE artifact_id IN " //NON-NLS
+ "(SELECT artifact_id FROM blackboard_artifacts WHERE artifact_type_id = " //NON-NLS + "(SELECT artifact_id FROM blackboard_artifacts WHERE artifact_type_id = " //NON-NLS
...@@ -1191,7 +1236,7 @@ private CaseDbSchemaVersionNumber updateFromSchema2toSchema3(CaseDbSchemaVersion ...@@ -1191,7 +1236,7 @@ private CaseDbSchemaVersionNumber updateFromSchema2toSchema3(CaseDbSchemaVersion
closeStatement(updateStatement); closeStatement(updateStatement);
closeResultSet(resultSet); closeResultSet(resultSet);
closeStatement(statement); closeStatement(statement);
connection.close(); closeStatement(statement2);
releaseSingleUserCaseWriteLock(); releaseSingleUserCaseWriteLock();
} }
} }
...@@ -2260,12 +2305,14 @@ private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema8dot7(CaseDbSchem ...@@ -2260,12 +2305,14 @@ private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema8dot7(CaseDbSchem
dateDataType = "INTEGER"; dateDataType = "INTEGER";
primaryKeyType = "INTEGER"; primaryKeyType = "INTEGER";
} }
statement.execute("ALTER TABLE data_source_info ADD COLUMN added_date_time "+ dateDataType); statement.execute("ALTER TABLE data_source_info ADD COLUMN added_date_time "+ dateDataType );
statement.execute("ALTER TABLE data_source_info ADD COLUMN acquisition_tool_settings TEXT"); statement.execute("ALTER TABLE data_source_info ADD COLUMN acquisition_tool_settings TEXT");
statement.execute("ALTER TABLE data_source_info ADD COLUMN acquisition_tool_name TEXT"); statement.execute("ALTER TABLE data_source_info ADD COLUMN acquisition_tool_name TEXT");
statement.execute("ALTER TABLE data_source_info ADD COLUMN acquisition_tool_version TEXT"); statement.execute("ALTER TABLE data_source_info ADD COLUMN acquisition_tool_version TEXT");
statement.execute("ALTER TABLE blackboard_artifact_types ADD COLUMN category_type INTEGER DEFAULT 0");
   
// create host table. // Create host table.
statement.execute("CREATE TABLE tsk_hosts (id " + primaryKeyType + " PRIMARY KEY, " statement.execute("CREATE TABLE tsk_hosts (id " + primaryKeyType + " PRIMARY KEY, "
+ "name TEXT NOT NULL, " // host name + "name TEXT NOT NULL, " // host name
+ "status INTEGER DEFAULT 0, " // to indicate if the host was merged/deleted + "status INTEGER DEFAULT 0, " // to indicate if the host was merged/deleted
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment