19 package org.sleuthkit.autopsy.coreutils;
 
   22 import java.io.IOException;
 
   23 import java.sql.Connection;
 
   24 import java.sql.DriverManager;
 
   25 import java.sql.ResultSet;
 
   26 import java.sql.SQLException;
 
   27 import java.sql.Statement;
 
   28 import java.util.ArrayList;
 
   29 import java.util.Collection;
 
   30 import java.util.List;
 
   31 import java.util.logging.Level;
 
   71         AbstractFile getAbstractFile() {
 
   82         this.dbAbstractFile = appSQLiteDBFileBundle.getAbstractFile();
 
   84         Class.forName(
"org.sqlite.JDBC"); 
 
   85         connection = DriverManager.getConnection(
"jdbc:sqlite:" + appSQLiteDBFileBundle.getFileCopy().getPath()); 
 
   86         statement = connection.createStatement();
 
  109             String dbFileName, 
boolean matchExactName, String parentPathSubstr) {
 
  111         List<AppSQLiteDB> appDbs = 
new ArrayList<>();
 
  113             Collection<AppSQLiteDBFileBundle> dbFileBundles = 
findAndCopySQLiteDB(dataSource, dbFileName, matchExactName, parentPathSubstr, 
false);
 
  114             dbFileBundles.forEach((dbFileBundle) -> {
 
  117                     appDbs.add(appSQLiteDB);
 
  118                 } 
catch (ClassNotFoundException | SQLException ex) {
 
  119                     Logger.
getLogger(
AppSQLiteDB.class.getName()).log(Level.SEVERE, String.format(
"Failed to open a DB connection for file = '%s' and path = '%s'.", dbFileBundle.dbAbstractFile.getName(), dbFileBundle.getFileCopy().getPath()), ex); 
 
  122         } 
catch (TskCoreException ex) {
 
  123             Logger.
getLogger(
AppSQLiteDB.class.getName()).log(Level.SEVERE, String.format(
"Error finding App database files with name = '%s' and path = '%s'.", dbFileName, parentPathSubstr), ex); 
 
  151             String dbPath, String dbAlias) 
throws SQLException {
 
  154             Collection<AppSQLiteDBFileBundle> dbFileBundles = 
findAndCopySQLiteDB(dataSource, dbName, 
true, dbPath, 
true);
 
  155             if (!dbFileBundles.isEmpty()) {
 
  157                 String attachDbSql = String.format(
"ATTACH DATABASE '%s' AS '%s'", dbFileBundle.getFileCopy().getPath(), dbAlias); 
 
  158                 statement.executeUpdate(attachDbSql);
 
  160                 return dbFileBundle.getAbstractFile();
 
  162         } 
catch (TskCoreException ex) {
 
  163             Logger.
getLogger(
AppSQLiteDB.class.getName()).log(Level.SEVERE, String.format(
"Error attaching to App database files with name = '%s' and path = '%s'.", dbName, dbPath), ex); 
 
  186     private static Collection<AppSQLiteDBFileBundle> 
findAndCopySQLiteDB(DataSource dataSource, String dbName,
 
  187             boolean matchExactName, String dbPath, 
boolean matchExactPath) 
throws TskCoreException {
 
  193             throw new TskCoreException(
"Failed to get current case.", ex);
 
  196         List<AppSQLiteDBFileBundle> dbFileBundles = 
new ArrayList<>();
 
  198         String localDiskPath = 
"";
 
  201         String parentPath = dbPath.replace(
"\\", 
"/");
 
  202         parentPath = SleuthkitCase.escapeSingleQuotes(parentPath);
 
  205         if (matchExactName) {
 
  206             whereClause = String.format(
"LOWER(name) = LOWER('%s')", dbName);
 
  208             whereClause = String.format(
"LOWER(name) LIKE LOWER('%%%s%%') AND LOWER(name) NOT LIKE LOWER('%%journal%%')", dbName);
 
  210         if (matchExactPath) {
 
  211             whereClause += String.format(
" AND LOWER(parent_path) = LOWER('%s')", parentPath);
 
  213             whereClause += String.format(
" AND LOWER(parent_path) LIKE LOWER('%%%s%%')", parentPath);
 
  215         whereClause += String.format(
" AND data_source_obj_id = %s", dataSource.getId());
 
  217         List<AbstractFile> absFiles = skCase.findAllFilesWhere(whereClause);
 
  218         for (AbstractFile absFile : absFiles) {
 
  221                         + File.separator + absFile.getId() + absFile.getName();
 
  222                 File jFile = 
new java.io.File(localDiskPath);
 
  223                 fileId = absFile.getId();
 
  231                 dbFileBundles.add(dbFileBundle);
 
  233             } 
catch (ReadContentInputStream.ReadContentInputStreamException ex) {
 
  234                 Logger.
getLogger(
AppSQLiteDB.class.getName()).log(Level.WARNING, String.format(
"Error reading content from file '%s' (id=%d).", absFile.getName(), fileId), ex); 
 
  236                 Logger.
getLogger(
AppSQLiteDB.class.getName()).log(Level.SEVERE, String.format(
"Error creating AppSQLiteDB  for file '%s' (id=%d) to  copied to '%s'.", absFile.getName(), fileId, localDiskPath), ex); 
 
  240         return dbFileBundles;
 
  251         String detachDbSql = String.format(
"DETACH DATABASE '%s'", dbAlias);
 
  252         statement.executeUpdate(detachDbSql); 
 
  265     public ResultSet 
runQuery(String queryStr) 
throws SQLException {
 
  266         ResultSet resultSet = null;
 
  268         if (null != queryStr) {
 
  269             resultSet = statement.executeQuery(queryStr); 
 
  284         } 
catch (SQLException e) {
 
  285             logger.log(Level.SEVERE, 
"Error closing the database", e); 
 
  298     public boolean columnExists(String tableName, String columnName) 
throws TskCoreException {
 
  301         Statement colExistsStatement = null;
 
  302         ResultSet resultSet = null;
 
  304             colExistsStatement = connection.createStatement();
 
  305             String tableInfoQuery = 
"PRAGMA table_info(%s)";  
 
  306             resultSet = colExistsStatement.executeQuery(String.format(tableInfoQuery, tableName));
 
  307             while (resultSet.next()) {
 
  308                 if (resultSet.getString(
"name").equalsIgnoreCase(columnName)) {
 
  313         } 
catch (SQLException ex) {
 
  314             throw new TskCoreException(
"Error checking if column  " + columnName + 
"exists ", ex);
 
  316             if (resultSet != null) {
 
  319                 } 
catch (SQLException ex2) {
 
  320                     logger.log(Level.WARNING, 
"Failed to close resultset after checking column", ex2);
 
  323             if (colExistsStatement != null) {
 
  325                     colExistsStatement.close();
 
  326                 } 
catch (SQLException ex2) {
 
  327                     logger.log(Level.SEVERE, 
"Error closing Statement", ex2); 
 
  342     public boolean tableExists(String tableName) 
throws TskCoreException {
 
  345         Statement tableExistsStatement = null;
 
  346         ResultSet resultSet = null;
 
  349             tableExistsStatement = connection.createStatement();
 
  350             resultSet = tableExistsStatement.executeQuery(
"SELECT name FROM sqlite_master WHERE type='table'");  
 
  351             while (resultSet.next()) {
 
  352                 if (resultSet.getString(
"name").equalsIgnoreCase(tableName)) { 
 
  357         } 
catch (SQLException ex) {
 
  358             throw new TskCoreException(
"Error checking if table  " + tableName + 
"exists ", ex);
 
  360             if (resultSet != null) {
 
  363                 } 
catch (SQLException ex2) {
 
  364                     logger.log(Level.WARNING, 
"Failed to close resultset after checking table", ex2);
 
  367             if (tableExistsStatement != null) {
 
  369                     tableExistsStatement.close();
 
  370                 } 
catch (SQLException ex2) {
 
  371                     logger.log(Level.SEVERE, 
"Error closing Statement", ex2); 
 
  394         if(sqliteFile.getParentPath().equalsIgnoreCase(
"/$carvedfiles/")) {
 
  403         List<AbstractFile> metaFiles = fileManager.
findFilesExactName(sqliteFile.getParent().getId(), metaFileName);
 
  405         if (metaFiles != null) {
 
  406             for (AbstractFile metaFile : metaFiles) {
 
  408                         + File.separator + sqliteFile.getId() + metaFile.getName();
 
  409                 File localMetaFile = 
new File(localDiskPath);
 
  410                 if (!localMetaFile.exists()) {
 
FileManager getFileManager()
 
boolean tableExists(String tableName)
 
String getTempDirectory()
 
static void findAndCopySQLiteMetaFile(AbstractFile sqliteFile, String metaFileName)
 
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
 
void detachDatabase(String dbAlias)
 
static Collection< AppSQLiteDB > findAppDatabases(DataSource dataSource, String dbFileName, boolean matchExactName, String parentPathSubstr)
 
AbstractFile attachDatabase(DataSource dataSource, String dbName, String dbPath, String dbAlias)
 
final Connection connection
 
AppSQLiteDB(AppSQLiteDBFileBundle appSQLiteDBFileBundle)
 
static Collection< AppSQLiteDBFileBundle > findAndCopySQLiteDB(DataSource dataSource, String dbName, boolean matchExactName, String dbPath, boolean matchExactPath)
 
SleuthkitCase getSleuthkitCase()
 
boolean columnExists(String tableName, String columnName)
 
final Statement statement
 
ResultSet runQuery(String queryStr)
 
List< AbstractFile > findFilesExactName(long parentId, String name)
 
synchronized static Logger getLogger(String name)
 
static Case getCurrentCaseThrows()
 
final AbstractFile dbAbstractFile
 
final AbstractFile dbAbstractFile