Sleuth Kit Java Bindings (JNI)  4.12.1
Java bindings for using The Sleuth Kit
CaseDbAccessManager.java
Go to the documentation of this file.
1 /*
2  * Sleuth Kit Data Model
3  *
4  * Copyright 2018-2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.datamodel;
20 
21 import com.google.common.annotations.Beta;
22 import java.sql.PreparedStatement;
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25 import java.sql.Statement;
26 import java.sql.Time;
27 import java.sql.Timestamp;
28 import java.text.MessageFormat;
29 import java.sql.Date;
30 import java.util.logging.Level;
31 import java.util.logging.Logger;
34 import static org.sleuthkit.datamodel.SleuthkitCase.closeStatement;
36 
42 public final class CaseDbAccessManager {
43 
47  public interface CaseDbAccessQueryCallback {
48 
57  void process(ResultSet resultSet);
58 
59  }
60 
61 
62  private static final Logger logger = Logger.getLogger(CaseDbAccessManager.class.getName());
63 
64  private final SleuthkitCase tskDB;
65 
73  this.tskDB = skCase;
74  }
75 
85  public boolean columnExists(String tableName, String columnName) throws TskCoreException {
86 
87  boolean doesColumnExists = false;
88  CaseDbTransaction localTrans = tskDB.beginTransaction();
89  try {
90  doesColumnExists = columnExists(tableName, columnName, localTrans);
91  localTrans.commit();
92  localTrans = null;
93  }
94  finally {
95  if (null != localTrans) {
96  try {
97  localTrans.rollback();
98  } catch (TskCoreException ex) {
99  logger.log(Level.SEVERE, "Failed to rollback transaction after exception", ex);
100  }
101  }
102  }
103 
104  return doesColumnExists;
105  }
106 
117  public boolean columnExists(String tableName, String columnName, CaseDbTransaction transaction) throws TskCoreException {
118 
119  boolean columnExists = false;
120  Statement statement = null;
121  ResultSet resultSet = null;
122  try {
123  CaseDbConnection connection = transaction.getConnection();
124  statement = connection.createStatement();
125  if (DbType.SQLITE == tskDB.getDatabaseType()) {
126  String tableInfoQuery = "PRAGMA table_info(%s)"; //NON-NLS
127  resultSet = statement.executeQuery(String.format(tableInfoQuery, tableName));
128  while (resultSet.next()) {
129  if (resultSet.getString("name").equalsIgnoreCase(columnName)) {
130  columnExists = true;
131  break;
132  }
133  }
134  }
135  else {
136  String tableInfoQueryTemplate = "SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='%s' AND column_name='%s')"; //NON-NLS
137  resultSet = statement.executeQuery(String.format(tableInfoQueryTemplate, tableName.toLowerCase(), columnName.toLowerCase()));
138  if (resultSet.next()) {
139  columnExists = resultSet.getBoolean(1);
140  }
141  }
142  }
143  catch (SQLException ex) {
144  throw new TskCoreException("Error checking if column " + columnName + "exists ", ex);
145  }
146  finally {
147  if (resultSet != null) {
148  try {
149  resultSet.close();
150  } catch (SQLException ex2) {
151  logger.log(Level.WARNING, "Failed to to close resultset after checking column", ex2);
152  }
153  }
154  closeStatement(statement);
155  }
156  return columnExists;
157  }
158 
167  public boolean tableExists(String tableName) throws TskCoreException {
168 
169  boolean doesTableExist = false;
170  CaseDbTransaction localTrans = tskDB.beginTransaction();
171  try {
172  doesTableExist = tableExists(tableName, localTrans);
173  localTrans.commit();
174  localTrans = null;
175  }
176  finally {
177  if (null != localTrans) {
178  try {
179  localTrans.rollback();
180  } catch (TskCoreException ex) {
181  logger.log(Level.SEVERE, "Failed to rollback transaction after exception", ex); //NON-NLS
182  }
183  }
184  }
185 
186  return doesTableExist;
187  }
188 
198  public boolean tableExists(String tableName, CaseDbTransaction transaction) throws TskCoreException {
199 
200  boolean tableExists = false;
201  Statement statement = null;
202  ResultSet resultSet = null;
203  try {
204  CaseDbConnection connection = transaction.getConnection();
205  statement = connection.createStatement();
206  if (DbType.SQLITE == tskDB.getDatabaseType()) {
207  resultSet = statement.executeQuery("SELECT name FROM sqlite_master WHERE type='table'"); //NON-NLS
208  while (resultSet.next()) {
209  if (resultSet.getString("name").equalsIgnoreCase(tableName)) { //NON-NLS
210  tableExists = true;
211  break;
212  }
213  }
214  }
215  else {
216  String tableInfoQueryTemplate = "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name='%s')"; //NON-NLS
217  resultSet = statement.executeQuery(String.format(tableInfoQueryTemplate, tableName.toLowerCase()));
218  if (resultSet.next()) {
219  tableExists = resultSet.getBoolean(1);
220  }
221  }
222  }
223  catch (SQLException ex) {
224  throw new TskCoreException("Error checking if table " + tableName + "exists ", ex);
225  } finally {
226  if (resultSet != null) {
227  try {
228  resultSet.close();
229  } catch (SQLException ex2) {
230  logger.log(Level.WARNING, "Failed to to close resultset after checking table", ex2);
231  }
232  }
233  closeStatement(statement);
234  }
235  return tableExists;
236  }
237 
251  public void createTable(final String tableName, final String tableSchema) throws TskCoreException {
252 
253  validateTableName(tableName);
254  validateSQL(tableSchema);
255 
257  String createSQL = "CREATE TABLE IF NOT EXISTS " + tableName + " " + tableSchema;
258  try (CaseDbConnection connection = tskDB.getConnection();
259  Statement statement = connection.createStatement();) {
260  statement.execute(createSQL);
261  } catch (SQLException ex) {
262  throw new TskCoreException("Error creating table " + tableName, ex);
263  } finally {
265  }
266  }
267 
276  public void alterTable(final String tableName, final String alterSQL) throws TskCoreException {
277 
278  CaseDbTransaction localTrans = tskDB.beginTransaction();
279  try {
280  alterTable(tableName, alterSQL, localTrans);
281  localTrans.commit();
282  localTrans = null;
283  } finally {
284  if (null != localTrans) {
285  try {
286  localTrans.rollback();
287  } catch (TskCoreException ex) {
288  logger.log(Level.SEVERE, "Failed to rollback transaction after exception", ex);
289  }
290  }
291  }
292  }
293 
303  public void alterTable(final String tableName, final String alterSQL, final CaseDbTransaction transaction) throws TskCoreException {
304 
305  validateTableName(tableName);
306  validateSQL(alterSQL);
307 
308  CaseDbConnection connection = transaction.getConnection();
309 
310  Statement statement = null;
311  String sql = "ALTER TABLE " + tableName + " " + alterSQL;
312 
313  try {
314  statement = connection.createStatement();
315  statement.execute(sql);
316  } catch (SQLException ex) {
317  // SQLite occasionally returns false for columnExists() if a table was just created with that column
318  // leading to "duplicate column name" exception.
319  // We ignore this exception
320  if (DbType.SQLITE == tskDB.getDatabaseType() &&
321  alterSQL.toLowerCase().contains("add column") &&
322  ex.getMessage().toLowerCase().contains("duplicate column name")) {
323  logger.log(Level.WARNING, String.format("Column being added by SQL = %s already exists in table %s", alterSQL, tableName));
324  return;
325  }
326  throw new TskCoreException(String.format("Error altering table %s with SQL = %s", tableName, sql), ex);
327  } finally {
328  closeStatement(statement);
329  }
330  }
331 
346  public void createIndex(final String indexName, final String tableName, final String colsSQL) throws TskCoreException {
347 
348  validateTableName(tableName);
349  validateIndexName(indexName);
350  validateSQL(colsSQL);
351 
353  String indexSQL = "CREATE INDEX IF NOT EXISTS " + indexName + " ON " + tableName + " " + colsSQL; // NON-NLS
354  try (CaseDbConnection connection = tskDB.getConnection();
355  Statement statement = connection.createStatement(); ) {
356  statement.execute(indexSQL);
357  } catch (SQLException ex) {
358  throw new TskCoreException("Error creating index " + tableName, ex);
359  } finally {
361  }
362  }
363 
374  public long insert(final String tableName, final String sql) throws TskCoreException {
375 
376  CaseDbTransaction localTrans = tskDB.beginTransaction();
377  try {
378  long rowId = insert(tableName, sql, localTrans);
379  localTrans.commit();
380  localTrans = null;
381  return rowId;
382  } finally {
383  if (null != localTrans) {
384  try {
385  localTrans.rollback();
386  } catch (TskCoreException ex) {
387  logger.log(Level.SEVERE, "Failed to rollback transaction after exception", ex);
388  }
389  }
390  }
391 
392  }
393 
410  public long insert(final String tableName, final String sql, final CaseDbTransaction transaction) throws TskCoreException {
411  long rowId = 0;
412 
413  validateTableName(tableName);
414  validateSQL(sql);
415 
416  CaseDbConnection connection = transaction.getConnection();
417 
418  PreparedStatement statement = null;
419  ResultSet resultSet;
420  String insertSQL = "INSERT";
421  if (DbType.SQLITE == tskDB.getDatabaseType()) {
422  insertSQL += " OR IGNORE";
423  }
424 
425  insertSQL = insertSQL+ " INTO " + tableName + " " + sql; // NON-NLS
426  try {
427  statement = connection.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS);
428  connection.executeUpdate(statement);
429 
430  resultSet = statement.getGeneratedKeys();
431  if (resultSet.next()) {
432  rowId = resultSet.getLong(1); //last_insert_rowid()
433  }
434  } catch (SQLException ex) {
435  throw new TskCoreException("Error inserting row in table " + tableName + " with sql = "+ insertSQL, ex);
436  } finally {
437  closeStatement(statement);
438  }
439 
440  return rowId;
441  }
442 
457  public long insertOrUpdate(final String tableName, final String sql) throws TskCoreException {
458 
459  CaseDbTransaction localTrans = tskDB.beginTransaction();
460  try {
461  long rowId = insertOrUpdate(tableName, sql, localTrans);
462  localTrans.commit();
463  localTrans = null;
464  return rowId;
465  } finally {
466  if (null != localTrans) {
467  try {
468  localTrans.rollback();
469  } catch (TskCoreException ex) {
470  logger.log(Level.SEVERE, "Failed to rollback transaction after exception", ex);
471  }
472  }
473  }
474 
475  }
476 
493  public long insertOrUpdate(final String tableName, final String sql, final CaseDbTransaction transaction) throws TskCoreException {
494  long rowId = 0;
495 
496  validateTableName(tableName);
497  validateSQL(sql);
498 
499  CaseDbConnection connection = transaction.getConnection();
500 
501  PreparedStatement statement = null;
502  ResultSet resultSet;
503  String insertSQL = "INSERT";
504  if (DbType.SQLITE == tskDB.getDatabaseType()) {
505  insertSQL += " OR REPLACE";
506  }
507 
508  insertSQL += " INTO " + tableName + " " + sql; // NON-NLS
509  try {
510  statement = connection.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS);
511  connection.executeUpdate(statement);
512 
513  resultSet = statement.getGeneratedKeys();
514  resultSet.next();
515  rowId = resultSet.getLong(1); //last_insert_rowid()
516  } catch (SQLException ex) {
517  throw new TskCoreException("Error inserting row in table " + tableName + " with sql = "+ insertSQL, ex);
518  } finally {
519  closeStatement(statement);
520  }
521 
522  return rowId;
523  }
524 
538  @Beta
539  public CaseDbPreparedStatement prepareUpdate(String tableName, String sql, CaseDbTransaction trans) throws TskCoreException {
540  validateTableName(tableName);
541  validateSQL(sql);
542 
543  String updateSQL = "UPDATE " + tableName + " " + sql; // NON-NLS
544 
545  try {
546  return new CaseDbPreparedStatement(StatementType.UPDATE, updateSQL, trans);
547  } catch (SQLException ex) {
548  throw new TskCoreException("Error creating update prepared statement for query:\n" + updateSQL, ex);
549  }
550  }
551 
559  @Beta
560  public void update(CaseDbPreparedStatement preparedStatement) throws TskCoreException {
561 
562  if (!preparedStatement.getType().equals(StatementType.UPDATE)) {
563  throw new TskCoreException("CaseDbPreparedStatement has incorrect type for update operation");
564  }
565 
566  try {
567  preparedStatement.getStatement().executeUpdate();
568  } catch (SQLException ex) {
569  throw new TskCoreException("Error updating row in table " + "" + " with sql = "+ "", ex);
570  }
571  }
572 
581  public void update(final String tableName, final String sql) throws TskCoreException {
582  CaseDbTransaction localTrans = tskDB.beginTransaction();
583  try {
584  update(tableName, sql, localTrans);
585  localTrans.commit();
586  localTrans = null;
587  } finally {
588  if (null != localTrans) {
589  try {
590  localTrans.rollback();
591  } catch (TskCoreException ex) {
592  logger.log(Level.SEVERE, "Failed to rollback transaction after exception", ex);
593  }
594  }
595  }
596  }
597 
598 
609  public void update(final String tableName, final String sql, CaseDbTransaction transaction ) throws TskCoreException {
610 
611  validateTableName(tableName);
612  validateSQL(sql);
613 
614  CaseDbConnection connection = transaction.getConnection();
615 
616  Statement statement = null;
617  String updateSQL = "UPDATE " + tableName + " " + sql; // NON-NLS
618 
619  try {
620  statement = connection.createStatement();
621  statement.executeUpdate(updateSQL);
622  } catch (SQLException ex) {
623  throw new TskCoreException("Error Updating table " + tableName, ex);
624  } finally {
625  closeStatement(statement);
626  }
627  }
628 
637  public void select(final String sql, final CaseDbAccessQueryCallback queryCallback) throws TskCoreException {
638 
639  if (queryCallback == null) {
640  throw new TskCoreException("Callback is null");
641  }
642 
643  validateSQL(sql);
644 
646  String selectSQL = "SELECT " + sql; // NON-NLS
647  try (CaseDbConnection connection = tskDB.getConnection();
648  Statement statement = connection.createStatement();
649  ResultSet resultSet = statement.executeQuery(selectSQL)) {
650  queryCallback.process(resultSet);
651  } catch (SQLException ex) {
652  throw new TskCoreException("Error running SELECT query.", ex);
653  } finally {
655  }
656  }
657 
676  @Beta
678  String selectSQL = "SELECT " + sql; // NON-NLS
679  try {
680  return new CaseDbPreparedStatement(StatementType.SELECT, selectSQL, false);
681  } catch (SQLException ex) {
682  throw new TskCoreException("Error creating select prepared statement for query:\n" + selectSQL, ex);
683  }
684  }
685 
697  @Beta
699  validateSQL(sql);
700 
701  String selectSQL = "SELECT " + sql; // NON-NLS
702 
703  try {
704  return new CaseDbPreparedStatement(StatementType.SELECT, selectSQL, trans);
705  } catch (SQLException ex) {
706  throw new TskCoreException("Error creating select prepared statement for query:\n" + selectSQL, ex);
707  }
708  }
709 
710 
719  @Beta
720  public void select(CaseDbPreparedStatement preparedStatement, CaseDbAccessQueryCallback queryCallback) throws TskCoreException {
721  if (!preparedStatement.getType().equals(StatementType.SELECT)) {
722  throw new TskCoreException("CaseDbPreparedStatement has incorrect type for select operation");
723  }
724 
725  try (ResultSet resultSet = preparedStatement.getStatement().executeQuery()) {
726  queryCallback.process(resultSet);
727  } catch (SQLException ex) {
728  throw new TskCoreException(MessageFormat.format("Error running SELECT query:\n{0}", preparedStatement.getOriginalSql()), ex);
729  }
730  }
731 
747  @Beta
748  public CaseDbPreparedStatement prepareInsert(String tableName, String sql, CaseDbTransaction trans) throws TskCoreException {
749  validateTableName(tableName);
750  validateSQL(sql);
751 
752  String insertSQL = "INSERT";
753  if (DbType.SQLITE == tskDB.getDatabaseType()) {
754  insertSQL += " OR IGNORE";
755  }
756  insertSQL = insertSQL + " INTO " + tableName + " " + sql; // NON-NLS
757 
758  try {
759  return new CaseDbPreparedStatement(StatementType.INSERT, insertSQL, trans);
760  } catch (SQLException ex) {
761  throw new TskCoreException("Error creating insert prepared statement for query:\n" + insertSQL, ex);
762  }
763  }
764 
772  @Beta
773  public void insert(CaseDbPreparedStatement preparedStatement) throws TskCoreException {
774 
775  if (!preparedStatement.getType().equals(StatementType.INSERT)) {
776  throw new TskCoreException("CaseDbPreparedStatement has incorrect type for insert operation");
777  }
778 
779  try {
780  preparedStatement.getStatement().executeUpdate();
781  } catch (SQLException ex) {
782  throw new TskCoreException("Error inserting row in table " + "" + " with sql = "+ "", ex);
783  }
784  }
785 
794  public void delete(final String tableName, final String sql ) throws TskCoreException {
795  validateTableName(tableName);
796  validateSQL(sql);
797 
799  String deleteSQL = "DELETE FROM " + tableName + " " + sql; // NON-NLS
800  try (CaseDbConnection connection = tskDB.getConnection();
801  Statement statement = connection.createStatement();) {
802  statement.executeUpdate(deleteSQL);
803  } catch (SQLException ex) {
804  throw new TskCoreException("Error deleting row from table " + tableName, ex);
805  } finally {
807  }
808  }
809 
818  private void validateTableName(String tableName) throws TskCoreException {
819 
820  if (SleuthkitCase.getCoreTableNames().contains(tableName.toLowerCase())) {
821  throw new TskCoreException("Attempt to modify a core TSK table " + tableName);
822  }
823  if (tableName.toLowerCase().startsWith("tsk_")) {
824  throw new TskCoreException("Modifying tables with tsk_ prefix is not allowed. ");
825  }
826  }
827 
836  private void validateIndexName(String indexName) throws TskCoreException {
837 
838  if (indexName.isEmpty()) {
839  throw new TskCoreException("Invalid index name " + indexName);
840  }
841 
842  if (SleuthkitCase.getCoreIndexNames().contains(indexName.toLowerCase())) {
843  throw new TskCoreException("Attempt to modify a core TSK index " + indexName);
844  }
845  }
846 
854  private void validateSQL(String sql) throws TskCoreException {
855  /*
856  * TODO (JIRA-5950): Need SQL injection defense in CaseDbAccessManager
857  */
858  }
859 
863  private enum LockType {
864  READ,
865  WRITE,
866  NONE;
867  }
868 
872  private enum StatementType {
873  SELECT,
874  INSERT,
875  UPDATE;
876  }
877 
882  @Beta
883  public class CaseDbPreparedStatement implements AutoCloseable {
884 
885  private final CaseDbConnection connection;
886  private final PreparedStatement preparedStatement;
887  private final String originalSql;
888  private final LockType lockType;
889  private final StatementType type;
890 
912  private CaseDbPreparedStatement(StatementType type, String query, boolean isWriteLockRequired) throws SQLException, TskCoreException {
913  if (isWriteLockRequired) {
915  this.lockType = LockType.WRITE;
916  } else {
918  this.lockType = LockType.READ;
919  }
920  this.connection = tskDB.getConnection();
921  this.preparedStatement = connection.getPreparedStatement(query, Statement.NO_GENERATED_KEYS);
922  this.originalSql = query;
923  this.type = type;
924  }
925 
936  private CaseDbPreparedStatement(StatementType type, String query, CaseDbTransaction trans) throws SQLException, TskCoreException {
937  this.lockType = LockType.NONE;
938  this.connection = trans.getConnection();
939  this.preparedStatement = connection.getPreparedStatement(query, Statement.NO_GENERATED_KEYS);
940  this.originalSql = query;
941  this.type = type;
942  }
943 
949  private PreparedStatement getStatement() {
950  return preparedStatement;
951  }
952 
958  private StatementType getType() {
959  return type;
960  }
961 
967  private String getOriginalSql() {
968  return originalSql;
969  }
970 
976  public void reset() throws TskCoreException {
977  try {
978  preparedStatement.clearParameters();
979  } catch (SQLException ex) {
980  throw new TskCoreException("An error occurred while clearing parameters.", ex);
981  }
982  }
983 
992  public void setBoolean(int parameterIndex, boolean x) throws TskCoreException {
993  try {
994  preparedStatement.setBoolean(parameterIndex, x);
995  } catch (SQLException ex) {
996  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
997  }
998  }
999 
1008  public void setByte(int parameterIndex, byte x) throws TskCoreException {
1009  try {
1010  preparedStatement.setByte(parameterIndex, x);
1011  } catch (SQLException ex) {
1012  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1013  }
1014  }
1015 
1024  public void setInt(int parameterIndex, int x) throws TskCoreException {
1025  try {
1026  preparedStatement.setInt(parameterIndex, x);
1027  } catch (SQLException ex) {
1028  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1029  }
1030  }
1031 
1040  public void setLong(int parameterIndex, long x) throws TskCoreException {
1041  try {
1042  preparedStatement.setLong(parameterIndex, x);
1043  } catch (SQLException ex) {
1044  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1045  }
1046  }
1047 
1056  public void setDouble(int parameterIndex, double x) throws TskCoreException {
1057  try {
1058  preparedStatement.setDouble(parameterIndex, x);
1059  } catch (SQLException ex) {
1060  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1061  }
1062  }
1063 
1072  public void setString(int parameterIndex, String x) throws TskCoreException {
1073  try {
1074  preparedStatement.setString(parameterIndex, x);
1075  } catch (SQLException ex) {
1076  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1077  }
1078  }
1079 
1088  public void setDate(int parameterIndex, Date x) throws TskCoreException {
1089  try {
1090  preparedStatement.setDate(parameterIndex, x);
1091  } catch (SQLException ex) {
1092  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1093  }
1094  }
1095 
1104  public void setTime(int parameterIndex, Time x) throws TskCoreException {
1105  try {
1106  preparedStatement.setTime(parameterIndex, x);
1107  } catch (SQLException ex) {
1108  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1109  }
1110  }
1111 
1120  public void setTimestamp(int parameterIndex, Timestamp x) throws TskCoreException {
1121  try {
1122  preparedStatement.setTimestamp(parameterIndex, x);
1123  } catch (SQLException ex) {
1124  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1125  }
1126  }
1127 
1138  public void setObject(int parameterIndex, Object x) throws TskCoreException {
1139  try {
1140  preparedStatement.setObject(parameterIndex, x);
1141  } catch (SQLException ex) {
1142  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1143  }
1144  }
1145 
1146  @Override
1147  public void close() throws SQLException {
1148 
1149  // Don't close the statement/connection or release a lock if we were supplied a transaction.
1150  // Everything will be handled when the transaction is closed.
1151  if (lockType.equals(LockType.NONE)) {
1152  return;
1153  }
1154 
1155  connection.close();
1156  if (lockType.equals(LockType.WRITE)) {
1158  } else {
1160  }
1161  }
1162  }
1163 
1164 }
boolean tableExists(String tableName, CaseDbTransaction transaction)
long insertOrUpdate(final String tableName, final String sql)
void update(final String tableName, final String sql)
long insert(final String tableName, final String sql, final CaseDbTransaction transaction)
CaseDbPreparedStatement prepareSelect(String sql)
void alterTable(final String tableName, final String alterSQL, final CaseDbTransaction transaction)
void createIndex(final String indexName, final String tableName, final String colsSQL)
boolean columnExists(String tableName, String columnName)
void createTable(final String tableName, final String tableSchema)
long insertOrUpdate(final String tableName, final String sql, final CaseDbTransaction transaction)
void insert(CaseDbPreparedStatement preparedStatement)
CaseDbPreparedStatement prepareUpdate(String tableName, String sql, CaseDbTransaction trans)
void alterTable(final String tableName, final String alterSQL)
void update(CaseDbPreparedStatement preparedStatement)
void select(final String sql, final CaseDbAccessQueryCallback queryCallback)
CaseDbPreparedStatement prepareInsert(String tableName, String sql, CaseDbTransaction trans)
void update(final String tableName, final String sql, CaseDbTransaction transaction)
CaseDbPreparedStatement prepareSelect(String sql, CaseDbTransaction trans)
long insert(final String tableName, final String sql)
void select(CaseDbPreparedStatement preparedStatement, CaseDbAccessQueryCallback queryCallback)
boolean columnExists(String tableName, String columnName, CaseDbTransaction transaction)

Copyright © 2011-2021 Brian Carrier. (carrier -at- sleuthkit -dot- org)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.