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);
251 CaseDbConnection connection = tskDB.getConnection();
254 Statement statement = null;
255 String createSQL =
"CREATE TABLE IF NOT EXISTS " + tableName +
" " + tableSchema;
257 statement = connection.createStatement();
258 statement.execute(createSQL);
259 }
catch (SQLException ex) {
262 closeStatement(statement);
285 if (null != localTrans) {
289 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
306 validateTableName(tableName);
307 validateSQL(alterSQL);
309 CaseDbConnection connection = transaction.getConnection();
310 transaction.acquireSingleUserCaseWriteLock();
312 Statement statement = null;
313 String sql =
"ALTER TABLE " + tableName +
" " + alterSQL;
316 statement = connection.createStatement();
317 statement.execute(sql);
318 }
catch (SQLException ex) {
323 alterSQL.toLowerCase().contains(
"add column") &&
324 ex.getMessage().toLowerCase().contains(
"duplicate column name")) {
325 logger.log(Level.WARNING, String.format(
"Column being added by SQL = %s already exists in table %s", alterSQL, tableName));
328 throw new TskCoreException(String.format(
"Error altering table %s with SQL = %s", tableName, sql), ex);
330 closeStatement(statement);
351 validateTableName(tableName);
352 validateIndexName(indexName);
353 validateSQL(colsSQL);
355 CaseDbConnection connection = tskDB.getConnection();
358 Statement statement = null;
359 String indexSQL =
"CREATE INDEX IF NOT EXISTS " + indexName +
" ON " + tableName +
" " + colsSQL;
361 statement = connection.createStatement();
362 statement.execute(indexSQL);
363 }
catch (SQLException ex) {
366 closeStatement(statement);
386 long rowId =
insert(tableName, sql, localTrans);
391 if (null != localTrans) {
395 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
421 validateTableName(tableName);
424 CaseDbConnection connection = transaction.getConnection();
425 transaction.acquireSingleUserCaseWriteLock();
427 PreparedStatement statement = null;
429 String insertSQL =
"INSERT";
431 insertSQL +=
" OR IGNORE";
434 insertSQL = insertSQL+
" INTO " + tableName +
" " + sql;
436 statement = connection.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS);
437 connection.executeUpdate(statement);
439 resultSet = statement.getGeneratedKeys();
440 if (resultSet.next()) {
441 rowId = resultSet.getLong(1);
443 }
catch (SQLException ex) {
444 throw new TskCoreException(
"Error inserting row in table " + tableName +
" with sql = "+ insertSQL, ex);
446 closeStatement(statement);
476 if (null != localTrans) {
480 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
506 validateTableName(tableName);
509 CaseDbConnection connection = transaction.getConnection();
510 transaction.acquireSingleUserCaseWriteLock();
512 PreparedStatement statement = null;
514 String insertSQL =
"INSERT";
516 insertSQL +=
" OR REPLACE";
519 insertSQL +=
" INTO " + tableName +
" " + sql;
521 statement = connection.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS);
522 connection.executeUpdate(statement);
524 resultSet = statement.getGeneratedKeys();
526 rowId = resultSet.getLong(1);
527 }
catch (SQLException ex) {
528 throw new TskCoreException(
"Error inserting row in table " + tableName +
" with sql = "+ insertSQL, ex);
530 closeStatement(statement);
548 update(tableName, sql, localTrans);
552 if (null != localTrans) {
556 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex);
575 validateTableName(tableName);
578 CaseDbConnection connection = transaction.getConnection();
579 transaction.acquireSingleUserCaseWriteLock();
581 Statement statement = null;
582 String updateSQL =
"UPDATE " + tableName +
" " + sql;
585 statement = connection.createStatement();
586 statement.executeUpdate(updateSQL);
587 }
catch (SQLException ex) {
590 closeStatement(statement);
605 if (queryCallback == null) {
611 CaseDbConnection connection = tskDB.getConnection();
614 Statement statement = null;
616 String selectSQL =
"SELECT " + sql;
618 statement = connection.createStatement();
619 resultSet = statement.executeQuery(selectSQL);
620 queryCallback.process(resultSet);
621 }
catch (SQLException ex) {
624 closeStatement(statement);
639 validateTableName(tableName);
642 CaseDbConnection connection = tskDB.getConnection();
645 Statement statement = null;
646 String deleteSQL =
"DELETE FROM " + tableName +
" " + sql;
648 statement = connection.createStatement();
649 statement.executeUpdate(deleteSQL);
650 }
catch (SQLException ex) {
651 throw new TskCoreException(
"Error deleting row from table " + tableName, ex);
653 closeStatement(statement);
669 if (
SleuthkitCase.getCoreTableNames().contains(tableName.toLowerCase())) {
670 throw new TskCoreException(
"Attempt to modify a core TSK table " + tableName);
672 if (tableName.toLowerCase().startsWith(
"tsk_")) {
673 throw new TskCoreException(
"Modifying tables with tsk_ prefix is not allowed. ");
685 private void validateIndexName(String indexName)
throws TskCoreException {
687 if (indexName.isEmpty()) {
688 throw new TskCoreException(
"Invalid index name " + indexName);
691 if (SleuthkitCase.getCoreIndexNames().contains(indexName.toLowerCase())) {
692 throw new TskCoreException(
"Attempt to modify a core TSK index " + indexName);
703 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)