19 package org.sleuthkit.datamodel;
21 import java.sql.PreparedStatement;
22 import java.sql.ResultSet;
23 import java.sql.SQLException;
24 import java.sql.Statement;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
52 void process(ResultSet resultSet);
82 boolean doesColumnExists =
false;
85 doesColumnExists =
columnExists(tableName, columnName, localTrans);
90 if (null != localTrans) {
94 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
99 return doesColumnExists;
115 Statement statement = null;
116 ResultSet resultSet = null;
118 CaseDbConnection connection = transaction.getConnection();
119 statement = connection.createStatement();
121 String tableInfoQuery =
"PRAGMA table_info(%s)";
122 resultSet = statement.executeQuery(String.format(tableInfoQuery, tableName));
123 while (resultSet.next()) {
124 if (resultSet.getString(
"name").equalsIgnoreCase(columnName)) {
131 String tableInfoQueryTemplate =
"SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='%s' AND column_name='%s')";
132 resultSet = statement.executeQuery(String.format(tableInfoQueryTemplate, tableName.toLowerCase(), columnName.toLowerCase()));
133 if (resultSet.next()) {
134 columnExists = resultSet.getBoolean(1);
138 catch (SQLException ex) {
139 throw new TskCoreException(
"Error checking if column " + columnName +
"exists ", ex);
142 if (resultSet != null) {
145 }
catch (SQLException ex2) {
146 logger.log(Level.WARNING,
"Failed to to close resultset after checking column", ex2);
149 closeStatement(statement);
164 boolean doesTableExist =
false;
167 doesTableExist =
tableExists(tableName, localTrans);
172 if (null != localTrans) {
176 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
181 return doesTableExist;
196 Statement statement = null;
197 ResultSet resultSet = null;
199 CaseDbConnection connection = transaction.getConnection();
200 statement = connection.createStatement();
202 resultSet = statement.executeQuery(
"SELECT name FROM sqlite_master WHERE type='table'");
203 while (resultSet.next()) {
204 if (resultSet.getString(
"name").equalsIgnoreCase(tableName)) {
211 String tableInfoQueryTemplate =
"SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name='%s')";
212 resultSet = statement.executeQuery(String.format(tableInfoQueryTemplate, tableName.toLowerCase()));
213 if (resultSet.next()) {
214 tableExists = resultSet.getBoolean(1);
218 catch (SQLException ex) {
219 throw new TskCoreException(
"Error checking if table " + tableName +
"exists ", ex);
221 if (resultSet != null) {
224 }
catch (SQLException ex2) {
225 logger.log(Level.WARNING,
"Failed to to close resultset after checking table", ex2);
228 closeStatement(statement);
248 validateTableName(tableName);
249 validateSQL(tableSchema);
252 String createSQL =
"CREATE TABLE IF NOT EXISTS " + tableName +
" " + tableSchema;
253 try (CaseDbConnection connection = tskDB.getConnection();
254 Statement statement = connection.createStatement();) {
255 statement.execute(createSQL);
256 }
catch (SQLException ex) {
279 if (null != localTrans) {
283 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
300 validateTableName(tableName);
301 validateSQL(alterSQL);
303 CaseDbConnection connection = transaction.getConnection();
305 Statement statement = null;
306 String sql =
"ALTER TABLE " + tableName +
" " + alterSQL;
309 statement = connection.createStatement();
310 statement.execute(sql);
311 }
catch (SQLException ex) {
316 alterSQL.toLowerCase().contains(
"add column") &&
317 ex.getMessage().toLowerCase().contains(
"duplicate column name")) {
318 logger.log(Level.WARNING, String.format(
"Column being added by SQL = %s already exists in table %s", alterSQL, tableName));
321 throw new TskCoreException(String.format(
"Error altering table %s with SQL = %s", tableName, sql), ex);
323 closeStatement(statement);
343 validateTableName(tableName);
344 validateIndexName(indexName);
345 validateSQL(colsSQL);
348 String indexSQL =
"CREATE INDEX IF NOT EXISTS " + indexName +
" ON " + tableName +
" " + colsSQL;
349 try (CaseDbConnection connection = tskDB.getConnection();
350 Statement statement = connection.createStatement(); ) {
351 statement.execute(indexSQL);
352 }
catch (SQLException ex) {
373 long rowId =
insert(tableName, sql, localTrans);
378 if (null != localTrans) {
382 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
408 validateTableName(tableName);
411 CaseDbConnection connection = transaction.getConnection();
413 PreparedStatement statement = null;
415 String insertSQL =
"INSERT";
417 insertSQL +=
" OR IGNORE";
420 insertSQL = insertSQL+
" INTO " + tableName +
" " + sql;
422 statement = connection.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS);
423 connection.executeUpdate(statement);
425 resultSet = statement.getGeneratedKeys();
426 if (resultSet.next()) {
427 rowId = resultSet.getLong(1);
429 }
catch (SQLException ex) {
430 throw new TskCoreException(
"Error inserting row in table " + tableName +
" with sql = "+ insertSQL, ex);
432 closeStatement(statement);
461 if (null != localTrans) {
465 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
491 validateTableName(tableName);
494 CaseDbConnection connection = transaction.getConnection();
496 PreparedStatement statement = null;
498 String insertSQL =
"INSERT";
500 insertSQL +=
" OR REPLACE";
503 insertSQL +=
" INTO " + tableName +
" " + sql;
505 statement = connection.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS);
506 connection.executeUpdate(statement);
508 resultSet = statement.getGeneratedKeys();
510 rowId = resultSet.getLong(1);
511 }
catch (SQLException ex) {
512 throw new TskCoreException(
"Error inserting row in table " + tableName +
" with sql = "+ insertSQL, ex);
514 closeStatement(statement);
531 update(tableName, sql, localTrans);
535 if (null != localTrans) {
539 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
558 validateTableName(tableName);
561 CaseDbConnection connection = transaction.getConnection();
563 Statement statement = null;
564 String updateSQL =
"UPDATE " + tableName +
" " + sql;
567 statement = connection.createStatement();
568 statement.executeUpdate(updateSQL);
569 }
catch (SQLException ex) {
572 closeStatement(statement);
586 if (queryCallback == null) {
593 String selectSQL =
"SELECT " + sql;
594 try (CaseDbConnection connection = tskDB.getConnection();
595 Statement statement = connection.createStatement();
596 ResultSet resultSet = statement.executeQuery(selectSQL)) {
597 queryCallback.process(resultSet);
598 }
catch (SQLException ex) {
614 validateTableName(tableName);
618 String deleteSQL =
"DELETE FROM " + tableName +
" " + sql;
619 try (CaseDbConnection connection = tskDB.getConnection();
620 Statement statement = connection.createStatement();) {
621 statement.executeUpdate(deleteSQL);
622 }
catch (SQLException ex) {
623 throw new TskCoreException(
"Error deleting row from table " + tableName, ex);
639 if (
SleuthkitCase.getCoreTableNames().contains(tableName.toLowerCase())) {
640 throw new TskCoreException(
"Attempt to modify a core TSK table " + tableName);
642 if (tableName.toLowerCase().startsWith(
"tsk_")) {
643 throw new TskCoreException(
"Modifying tables with tsk_ prefix is not allowed. ");
655 private void validateIndexName(String indexName)
throws TskCoreException {
657 if (indexName.isEmpty()) {
658 throw new TskCoreException(
"Invalid index name " + indexName);
661 if (SleuthkitCase.getCoreIndexNames().contains(indexName.toLowerCase())) {
662 throw new TskCoreException(
"Attempt to modify a core TSK index " + indexName);
673 private void validateSQL(String sql)
throws TskCoreException {
void process(ResultSet resultSet)
boolean tableExists(String tableName, CaseDbTransaction transaction)
long insertOrUpdate(final String tableName, final String sql)
CaseDbTransaction beginTransaction()
void update(final String tableName, final String sql)
long insert(final String tableName, final String sql, final CaseDbTransaction transaction)
void alterTable(final String tableName, final String alterSQL, final CaseDbTransaction transaction)
boolean tableExists(String tableName)
void createIndex(final String indexName, final String tableName, final String colsSQL)
boolean columnExists(String tableName, String columnName)
void releaseSingleUserCaseReadLock()
void createTable(final String tableName, final String tableSchema)
long insertOrUpdate(final String tableName, final String sql, final CaseDbTransaction transaction)
void acquireSingleUserCaseWriteLock()
void releaseSingleUserCaseWriteLock()
void alterTable(final String tableName, final String alterSQL)
void select(final String sql, final CaseDbAccessQueryCallback queryCallback)
void update(final String tableName, final String sql, CaseDbTransaction transaction)
void acquireSingleUserCaseReadLock()
long insert(final String tableName, final String sql)
boolean columnExists(String tableName, String columnName, CaseDbTransaction transaction)