mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
Fixed the temp directory file collisions during reading and refactored the localDiskPath out
This commit is contained in:
parent
3bf5d1461f
commit
c31044a657
@ -22,8 +22,10 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,10 +34,17 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractReader implements AutoCloseable {
|
public abstract class AbstractReader implements AutoCloseable {
|
||||||
|
|
||||||
public AbstractReader(AbstractFile file, String localDiskPath)
|
private final String localDiskPath;
|
||||||
|
|
||||||
|
public AbstractReader(Content file)
|
||||||
throws FileReaderInitException {
|
throws FileReaderInitException {
|
||||||
|
|
||||||
writeDataSourceToLocalDisk(file, localDiskPath);
|
try {
|
||||||
|
localDiskPath = getLocalDiskPath(file);
|
||||||
|
writeDataSourceToLocalDisk(file);
|
||||||
|
} catch (FileReaderInitException ex) {
|
||||||
|
throw new FileReaderInitException(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,7 +57,7 @@ public abstract class AbstractReader implements AutoCloseable {
|
|||||||
* @throws NoCurrentCaseException Current case closed during file copying
|
* @throws NoCurrentCaseException Current case closed during file copying
|
||||||
* @throws TskCoreException Exception finding files from abstract file
|
* @throws TskCoreException Exception finding files from abstract file
|
||||||
*/
|
*/
|
||||||
private void writeDataSourceToLocalDisk(AbstractFile file, String localDiskPath)
|
private void writeDataSourceToLocalDisk(Content file)
|
||||||
throws FileReaderInitException {
|
throws FileReaderInitException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -61,6 +70,30 @@ public abstract class AbstractReader implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLocalDiskPath() {
|
||||||
|
return localDiskPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a local disk path for abstract file contents to be copied. All
|
||||||
|
* file sources must be copied to local disk to be opened by abstract
|
||||||
|
* reader.
|
||||||
|
*
|
||||||
|
* @param file The database abstract file
|
||||||
|
*
|
||||||
|
* @return Valid local path for copying
|
||||||
|
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private String getLocalDiskPath(Content file) throws FileReaderInitException {
|
||||||
|
try {
|
||||||
|
return Case.getCurrentCaseThrows().getTempDirectory()
|
||||||
|
+ File.separator + file.getId() + file.getName();
|
||||||
|
} catch(NoCurrentCaseException ex) {
|
||||||
|
throw new FileReaderInitException("No current case open when trying to get temp directory", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the a mapping of table names to table schemas (may be in the form of
|
* Return the a mapping of table names to table schemas (may be in the form of
|
||||||
* headers or create table statements for databases).
|
* headers or create table statements for databases).
|
||||||
|
@ -37,9 +37,9 @@ import org.apache.poi.ss.usermodel.Sheet;
|
|||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
|
||||||
import com.monitorjbl.xlsx.StreamingReader;
|
import com.monitorjbl.xlsx.StreamingReader;
|
||||||
import org.apache.poi.hssf.OldExcelFormatException;
|
import org.apache.poi.hssf.OldExcelFormatException;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads excel files and implements the abstract reader api for interfacing with
|
* Reads excel files and implements the abstract reader api for interfacing with
|
||||||
@ -58,10 +58,10 @@ public final class ExcelReader extends AbstractReader {
|
|||||||
private String LOCAL_DISK_PATH;
|
private String LOCAL_DISK_PATH;
|
||||||
private String ACTIVE_MIME_TYPE;
|
private String ACTIVE_MIME_TYPE;
|
||||||
|
|
||||||
public ExcelReader(AbstractFile file, String localDiskPath, String mimeType)
|
public ExcelReader(Content file, String mimeType)
|
||||||
throws FileReaderInitException {
|
throws FileReaderInitException {
|
||||||
super(file, localDiskPath);
|
super(file);
|
||||||
this.LOCAL_DISK_PATH = localDiskPath;
|
this.LOCAL_DISK_PATH = super.getLocalDiskPath();
|
||||||
this.ACTIVE_MIME_TYPE = mimeType;
|
this.ACTIVE_MIME_TYPE = mimeType;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -19,40 +19,44 @@
|
|||||||
package org.sleuthkit.autopsy.tabulardatareader;
|
package org.sleuthkit.autopsy.tabulardatareader;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException;
|
import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for creating the correct reader given the mime type of a file.
|
* Factory for creating the correct reader given the mime type of a file.
|
||||||
*/
|
*/
|
||||||
public final class FileReaderFactory {
|
public final class FileReaderFactory {
|
||||||
|
|
||||||
private FileReaderFactory() {
|
private FileReaderFactory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates the appropriate reader given the mimeType argument. Currently
|
* Instantiates the appropriate reader given the mimeType argument.
|
||||||
* supports SQLite files and Excel files (.xls and .xlsx). BIFF5 format of .xls
|
* Currently supports SQLite files and Excel files (.xls and .xlsx). BIFF5
|
||||||
* is not supported.
|
* format of .xls is not supported.
|
||||||
*
|
*
|
||||||
* @param mimeType mimeType passed in from the ingest module
|
* @param mimeType mimeType passed in from the ingest module g * @param file
|
||||||
g * @param file current file under inspection
|
* current file under inspection
|
||||||
* @param localDiskPath path for abstract file contents to be written
|
*
|
||||||
|
* @param file Content file to be copied into
|
||||||
|
*
|
||||||
* @return The correct reader class needed to read the file contents
|
* @return The correct reader class needed to read the file contents
|
||||||
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException
|
||||||
*/
|
*/
|
||||||
public static AbstractReader createReader(String mimeType, AbstractFile file,
|
public static AbstractReader createReader(Content file, String mimeType) throws FileReaderInitException {
|
||||||
String localDiskPath) throws FileReaderInitException {
|
|
||||||
switch (mimeType) {
|
switch (mimeType) {
|
||||||
case "application/x-sqlite3":
|
case "application/x-sqlite3":
|
||||||
return new SQLiteReader(file, localDiskPath);
|
return new SQLiteReader(file);
|
||||||
case "application/vnd.ms-excel":
|
case "application/vnd.ms-excel":
|
||||||
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
||||||
try {
|
try {
|
||||||
return new ExcelReader(file, localDiskPath, mimeType);
|
return new ExcelReader(file, mimeType);
|
||||||
//Catches runtime exceptions being emitted from Apache
|
//Catches runtime exceptions being emitted from Apache
|
||||||
//POI (such as EncryptedDocumentException) and wraps them
|
//POI (such as EncryptedDocumentException) and wraps them
|
||||||
//into FileReaderInitException to be caught and logged
|
//into FileReaderInitException to be caught and logged
|
||||||
//in the ingest module.
|
//in the ingest module.
|
||||||
} catch(Exception poiInitException) {
|
} catch (Exception poiInitException) {
|
||||||
throw new FileReaderInitException(poiInitException);
|
throw new FileReaderInitException(poiInitException);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -43,6 +43,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
@ -50,152 +51,166 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* Reads sqlite databases and returns results in a list collection.
|
* Reads sqlite databases and returns results in a list collection.
|
||||||
*/
|
*/
|
||||||
public final class SQLiteReader extends AbstractReader {
|
public final class SQLiteReader extends AbstractReader {
|
||||||
|
|
||||||
private final Connection connection;
|
private final Connection connection;
|
||||||
private final static IngestServices services = IngestServices.getInstance();
|
private final static IngestServices services = IngestServices.getInstance();
|
||||||
private final static Logger logger = services.getLogger(SQLiteReader.class.getName());
|
private final static Logger logger = services.getLogger(SQLiteReader.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes data source file contents to local disk and opens a sqlite JDBC
|
* Writes data source file contents to local disk and opens a sqlite JDBC
|
||||||
* connection.
|
* connection.
|
||||||
*
|
*
|
||||||
* @param sqliteDbFile Data source abstract file
|
* @param sqliteDbFile Data source content
|
||||||
* @param localDiskPath Location for database contents to be copied to
|
*
|
||||||
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException
|
||||||
*/
|
*/
|
||||||
public SQLiteReader(AbstractFile sqliteDbFile, String localDiskPath) throws FileReaderInitException {
|
public SQLiteReader(Content sqliteDbFile) throws FileReaderInitException {
|
||||||
super(sqliteDbFile, localDiskPath);
|
super(sqliteDbFile);
|
||||||
try {
|
try {
|
||||||
// Look for any meta files associated with this DB - WAL, SHM, etc.
|
// Look for any meta files associated with this DB - WAL, SHM, etc.
|
||||||
findAndCopySQLiteMetaFile(sqliteDbFile, sqliteDbFile.getName() + "-wal");
|
findAndCopySQLiteMetaFile(sqliteDbFile, sqliteDbFile.getName() + "-wal");
|
||||||
findAndCopySQLiteMetaFile(sqliteDbFile, sqliteDbFile.getName() + "-shm");
|
findAndCopySQLiteMetaFile(sqliteDbFile, sqliteDbFile.getName() + "-shm");
|
||||||
|
|
||||||
connection = getDatabaseConnection(localDiskPath);
|
connection = getDatabaseConnection(super.getLocalDiskPath());
|
||||||
} catch (ClassNotFoundException | SQLException |IOException |
|
} catch (ClassNotFoundException | SQLException | IOException
|
||||||
NoCurrentCaseException | TskCoreException ex) {
|
| NoCurrentCaseException | TskCoreException ex) {
|
||||||
throw new FileReaderInitException(ex);
|
throw new FileReaderInitException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for a meta file associated with the give SQLite database. If found,
|
* Searches for a meta file associated with the give SQLite database. If
|
||||||
* copies the file to the local disk folder
|
* found, copies the file to the local disk folder
|
||||||
*
|
*
|
||||||
* @param sqliteFile file being processed
|
* @param sqliteFile file being processed
|
||||||
* @param metaFileName name of meta file to look for
|
* @param metaFileName name of meta file to look for
|
||||||
|
*
|
||||||
* @throws NoCurrentCaseException Case has been closed.
|
* @throws NoCurrentCaseException Case has been closed.
|
||||||
* @throws TskCoreException fileManager cannot find AbstractFile files.
|
* @throws TskCoreException fileManager cannot find AbstractFile
|
||||||
* @throws IOException Issue during writing to file.
|
* files.
|
||||||
|
* @throws IOException Issue during writing to file.
|
||||||
*/
|
*/
|
||||||
private void findAndCopySQLiteMetaFile(AbstractFile sqliteFile,
|
private void findAndCopySQLiteMetaFile(Content sqliteFile,
|
||||||
String metaFileName) throws NoCurrentCaseException, TskCoreException, IOException {
|
String metaFileName) throws NoCurrentCaseException, TskCoreException, IOException {
|
||||||
|
|
||||||
Case openCase = Case.getCurrentCaseThrows();
|
Case openCase = Case.getCurrentCaseThrows();
|
||||||
SleuthkitCase sleuthkitCase = openCase.getSleuthkitCase();
|
SleuthkitCase sleuthkitCase = openCase.getSleuthkitCase();
|
||||||
Services services = new Services(sleuthkitCase);
|
Services services = new Services(sleuthkitCase);
|
||||||
FileManager fileManager = services.getFileManager();
|
FileManager fileManager = services.getFileManager();
|
||||||
|
|
||||||
List<AbstractFile> metaFiles = fileManager.findFiles(
|
List<AbstractFile> metaFiles = fileManager.findFiles(
|
||||||
sqliteFile.getDataSource(), metaFileName,
|
sqliteFile.getDataSource(), metaFileName,
|
||||||
sqliteFile.getParent().getName());
|
sqliteFile.getParent().getName());
|
||||||
|
|
||||||
if (metaFiles != null) {
|
if (metaFiles != null) {
|
||||||
for (AbstractFile metaFile : metaFiles) {
|
for (AbstractFile metaFile : metaFiles) {
|
||||||
String tmpMetafilePathName = openCase.getTempDirectory() +
|
String tmpMetafilePathName = openCase.getTempDirectory()
|
||||||
File.separator + metaFile.getName();
|
+ File.separator + metaFile.getId() + metaFile.getName();
|
||||||
File tmpMetafile = new File(tmpMetafilePathName);
|
File tmpMetafile = new File(tmpMetafilePathName);
|
||||||
ContentUtils.writeToFile(metaFile, tmpMetafile);
|
ContentUtils.writeToFile(metaFile, tmpMetafile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a JDBC connection to the sqlite database specified by the path
|
* Opens a JDBC connection to the sqlite database specified by the path
|
||||||
* parameter.
|
* parameter.
|
||||||
*
|
*
|
||||||
* @param databasePath Local path of sqlite database
|
* @param databasePath Local path of sqlite database
|
||||||
* @return Connection JDBC connection, to be maintained and closed by the reader
|
*
|
||||||
|
* @return Connection JDBC connection, to be maintained and closed by the
|
||||||
|
* reader
|
||||||
|
*
|
||||||
* @throws ClassNotFoundException missing SQLite JDBC class
|
* @throws ClassNotFoundException missing SQLite JDBC class
|
||||||
* @throws SQLException Exception during opening database connection
|
* @throws SQLException Exception during opening database
|
||||||
|
* connection
|
||||||
*/
|
*/
|
||||||
private Connection getDatabaseConnection(String databasePath)
|
private Connection getDatabaseConnection(String databasePath)
|
||||||
throws ClassNotFoundException, SQLException {
|
throws ClassNotFoundException, SQLException {
|
||||||
|
|
||||||
// Load the SQLite JDBC driver, if necessary.
|
// Load the SQLite JDBC driver, if necessary.
|
||||||
Class.forName("org.sqlite.JDBC"); //NON-NLS
|
Class.forName("org.sqlite.JDBC"); //NON-NLS
|
||||||
return DriverManager.getConnection(
|
return DriverManager.getConnection(
|
||||||
"jdbc:sqlite:" + databasePath); //NON-NLS
|
"jdbc:sqlite:" + databasePath); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a map view of table names to table schemas (in the form of
|
* Retrieves a map view of table names to table schemas (in the form of
|
||||||
* CREATE TABLE statments).
|
* CREATE TABLE statments).
|
||||||
*
|
*
|
||||||
* @return A map of table names to table schemas
|
* @return A map of table names to table schemas
|
||||||
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getTableSchemas() throws FileReaderException {
|
public Map<String, String> getTableSchemas() throws FileReaderException {
|
||||||
|
|
||||||
Map<String, String> dbTablesMap = new TreeMap<>();
|
Map<String, String> dbTablesMap = new TreeMap<>();
|
||||||
|
|
||||||
try (Statement statement = connection.createStatement();
|
try (Statement statement = connection.createStatement();
|
||||||
ResultSet resultSet = statement.executeQuery(
|
ResultSet resultSet = statement.executeQuery(
|
||||||
"SELECT name, sql FROM sqlite_master " //NON-NLS
|
"SELECT name, sql FROM sqlite_master " //NON-NLS
|
||||||
+ " WHERE type= 'table' " //NON-NLS
|
+ " WHERE type= 'table' " //NON-NLS
|
||||||
+ " ORDER BY name;")){ //NON-NLS
|
+ " ORDER BY name;")) { //NON-NLS
|
||||||
|
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
String tableName = resultSet.getString("name"); //NON-NLS
|
String tableName = resultSet.getString("name"); //NON-NLS
|
||||||
String tableSQL = resultSet.getString("sql"); //NON-NLS
|
String tableSQL = resultSet.getString("sql"); //NON-NLS
|
||||||
dbTablesMap.put(tableName, tableSQL);
|
dbTablesMap.put(tableName, tableSQL);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new FileReaderException(ex);
|
throw new FileReaderException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dbTablesMap;
|
return dbTablesMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the total number of rows from a table in the SQLite database.
|
* Retrieves the total number of rows from a table in the SQLite database.
|
||||||
*
|
*
|
||||||
* @param tableName
|
* @param tableName
|
||||||
|
*
|
||||||
* @return Row count from tableName
|
* @return Row count from tableName
|
||||||
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Integer getRowCountFromTable(String tableName)
|
public Integer getRowCountFromTable(String tableName)
|
||||||
throws FileReaderException {
|
throws FileReaderException {
|
||||||
String quotedTableName = wrapTableNameStringWithQuotes(tableName);
|
String quotedTableName = wrapTableNameStringWithQuotes(tableName);
|
||||||
try (Statement statement = connection.createStatement();
|
try (Statement statement = connection.createStatement();
|
||||||
ResultSet resultSet = statement.executeQuery(
|
ResultSet resultSet = statement.executeQuery(
|
||||||
"SELECT count (*) as count FROM " + quotedTableName)){ //NON-NLS
|
"SELECT count (*) as count FROM " + quotedTableName)) { //NON-NLS
|
||||||
return resultSet.getInt("count"); //NON-NLS
|
return resultSet.getInt("count"); //NON-NLS
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new FileReaderException(ex);
|
throw new FileReaderException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all rows from a given table in the SQLite database. If only a
|
* Retrieves all rows from a given table in the SQLite database. If only a
|
||||||
* subset of rows are desired, see the overloaded function below.
|
* subset of rows are desired, see the overloaded function below.
|
||||||
*
|
*
|
||||||
* @param tableName
|
* @param tableName
|
||||||
* @return List of rows, where each row is
|
*
|
||||||
* represented as a column-value map.
|
* @return List of rows, where each row is represented as a column-value
|
||||||
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
* map.
|
||||||
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, Object>> getRowsFromTable(String tableName)
|
public List<Map<String, Object>> getRowsFromTable(String tableName)
|
||||||
throws FileReaderException {
|
throws FileReaderException {
|
||||||
//This method does not directly call its overloaded counterpart
|
//This method does not directly call its overloaded counterpart
|
||||||
//since the second parameter would need to be retreived from a call to
|
//since the second parameter would need to be retreived from a call to
|
||||||
//getTableRowCount().
|
//getTableRowCount().
|
||||||
String quotedTableName = wrapTableNameStringWithQuotes(tableName);
|
String quotedTableName = wrapTableNameStringWithQuotes(tableName);
|
||||||
try(Statement statement = connection.createStatement();
|
try (Statement statement = connection.createStatement();
|
||||||
ResultSet resultSet = statement.executeQuery(
|
ResultSet resultSet = statement.executeQuery(
|
||||||
"SELECT * FROM " + quotedTableName)) { //NON-NLS
|
"SELECT * FROM " + quotedTableName)) { //NON-NLS
|
||||||
return resultSetToList(resultSet);
|
return resultSetToList(resultSet);
|
||||||
@ -203,24 +218,27 @@ public final class SQLiteReader extends AbstractReader {
|
|||||||
throw new FileReaderException(ex);
|
throw new FileReaderException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a subset of the rows from a given table in the SQLite database.
|
* Retrieves a subset of the rows from a given table in the SQLite database.
|
||||||
*
|
*
|
||||||
* @param tableName
|
* @param tableName
|
||||||
* @param offset Desired start index (rows begin at 1)
|
* @param offset Desired start index (rows begin at 1)
|
||||||
* @param numRowsToRead Number of rows past the start index
|
* @param numRowsToRead Number of rows past the start index
|
||||||
* @return List of rows, where each row is
|
*
|
||||||
* represented as a column-value map.
|
* @return List of rows, where each row is represented as a column-value
|
||||||
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
* map.
|
||||||
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, Object>> getRowsFromTable(String tableName,
|
public List<Map<String, Object>> getRowsFromTable(String tableName,
|
||||||
int offset, int numRowsToRead) throws FileReaderException{
|
int offset, int numRowsToRead) throws FileReaderException {
|
||||||
String quotedTableName = wrapTableNameStringWithQuotes(tableName);
|
String quotedTableName = wrapTableNameStringWithQuotes(tableName);
|
||||||
try(Statement statement = connection.createStatement();
|
try (Statement statement = connection.createStatement();
|
||||||
ResultSet resultSet = statement.executeQuery(
|
ResultSet resultSet = statement.executeQuery(
|
||||||
"SELECT * FROM " + quotedTableName //NON-NLS
|
"SELECT * FROM " + quotedTableName //NON-NLS
|
||||||
+ " LIMIT " + Integer.toString(numRowsToRead) //NON-NLS
|
+ " LIMIT " + Integer.toString(numRowsToRead) //NON-NLS
|
||||||
+ " OFFSET " + Integer.toString(offset - 1))) { //NON-NLS
|
+ " OFFSET " + Integer.toString(offset - 1))) { //NON-NLS
|
||||||
return resultSetToList(resultSet);
|
return resultSetToList(resultSet);
|
||||||
@ -228,31 +246,34 @@ public final class SQLiteReader extends AbstractReader {
|
|||||||
throw new FileReaderException(ex);
|
throw new FileReaderException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps table name with quotation marks in case table name contains spaces.
|
* Wraps table name with quotation marks in case table name contains spaces.
|
||||||
* sqliteJDBC cannot read table names with spaces in them unless surrounded
|
* sqliteJDBC cannot read table names with spaces in them unless surrounded
|
||||||
* by quotation marks.
|
* by quotation marks.
|
||||||
*
|
*
|
||||||
* @param tableName
|
* @param tableName
|
||||||
|
*
|
||||||
* @return Input name: Result Table -> "Result Table"
|
* @return Input name: Result Table -> "Result Table"
|
||||||
*/
|
*/
|
||||||
private String wrapTableNameStringWithQuotes(String tableName) {
|
private String wrapTableNameStringWithQuotes(String tableName) {
|
||||||
return "\"" + tableName +"\"";
|
return "\"" + tableName + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a ResultSet (row results from a table read) into a list.
|
* Converts a ResultSet (row results from a table read) into a list.
|
||||||
*
|
*
|
||||||
* @param resultSet row results from a table read
|
* @param resultSet row results from a table read
|
||||||
* @return List of rows, where each row is
|
*
|
||||||
* represented as a column-value map.
|
* @return List of rows, where each row is represented as a column-value
|
||||||
* @throws SQLException occurs if ResultSet is closed while attempting to
|
* map.
|
||||||
* access it's data.
|
*
|
||||||
|
* @throws SQLException occurs if ResultSet is closed while attempting to
|
||||||
|
* access it's data.
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages("SQLiteReader.BlobNotShown.message=BLOB Data not shown")
|
@NbBundle.Messages("SQLiteReader.BlobNotShown.message=BLOB Data not shown")
|
||||||
private List<Map<String, Object>> resultSetToList(ResultSet resultSet) throws SQLException {
|
private List<Map<String, Object>> resultSetToList(ResultSet resultSet) throws SQLException {
|
||||||
|
|
||||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||||
int columns = metaData.getColumnCount();
|
int columns = metaData.getColumnCount();
|
||||||
List<Map<String, Object>> rowMap = new ArrayList<>();
|
List<Map<String, Object>> rowMap = new ArrayList<>();
|
||||||
@ -274,33 +295,36 @@ public final class SQLiteReader extends AbstractReader {
|
|||||||
|
|
||||||
return rowMap;
|
return rowMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a column view of the table. Maps the column name to a list of that
|
* Returns a column view of the table. Maps the column name to a list of
|
||||||
* column's values.
|
* that column's values.
|
||||||
*
|
*
|
||||||
* @param tableName
|
* @param tableName
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, List<Object>> getColumnsFromTable(String tableName)
|
public Map<String, List<Object>> getColumnsFromTable(String tableName)
|
||||||
throws FileReaderException {
|
throws FileReaderException {
|
||||||
|
|
||||||
String quotedTableName = wrapTableNameStringWithQuotes(tableName);
|
String quotedTableName = wrapTableNameStringWithQuotes(tableName);
|
||||||
try(Statement statement = connection.createStatement();
|
try (Statement statement = connection.createStatement();
|
||||||
ResultSet resultSet = statement.executeQuery(
|
ResultSet resultSet = statement.executeQuery(
|
||||||
"SELECT * FROM " + quotedTableName)) { //NON-NLS
|
"SELECT * FROM " + quotedTableName)) { //NON-NLS
|
||||||
|
|
||||||
Map<String, List<Object>> columnView = new HashMap<>();
|
Map<String, List<Object>> columnView = new HashMap<>();
|
||||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||||
int columns = metaData.getColumnCount();
|
int columns = metaData.getColumnCount();
|
||||||
for(int i = 1; i <= columns; i++) {
|
for (int i = 1; i <= columns; i++) {
|
||||||
columnView.put(metaData.getColumnName(i), new LinkedList<>());
|
columnView.put(metaData.getColumnName(i), new LinkedList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
for(int i = 1; i <= columns; i++) {
|
for (int i = 1; i <= columns; i++) {
|
||||||
if (resultSet.getObject(i) == null) {
|
if (resultSet.getObject(i) == null) {
|
||||||
columnView.get(metaData.getColumnName(i)).add("");
|
columnView.get(metaData.getColumnName(i)).add("");
|
||||||
} else {
|
} else {
|
||||||
@ -314,7 +338,7 @@ public final class SQLiteReader extends AbstractReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return columnView;
|
return columnView;
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new FileReaderException(ex);
|
throw new FileReaderException(ex);
|
||||||
@ -322,7 +346,7 @@ public final class SQLiteReader extends AbstractReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes underlying JDBC connection.
|
* Closes underlying JDBC connection.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user