Sleuth Kit Java Bindings (JNI)  4.11.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 
694  @Beta
695  public void select(CaseDbPreparedStatement preparedStatement, CaseDbAccessQueryCallback queryCallback) throws TskCoreException {
696  if (!preparedStatement.getType().equals(StatementType.SELECT)) {
697  throw new TskCoreException("CaseDbPreparedStatement has incorrect type for select operation");
698  }
699 
700  try (ResultSet resultSet = preparedStatement.getStatement().executeQuery()) {
701  queryCallback.process(resultSet);
702  } catch (SQLException ex) {
703  throw new TskCoreException(MessageFormat.format("Error running SELECT query:\n{0}", preparedStatement.getOriginalSql()), ex);
704  }
705  }
706 
722  @Beta
723  public CaseDbPreparedStatement prepareInsert(String tableName, String sql, CaseDbTransaction trans) throws TskCoreException {
724  validateTableName(tableName);
725  validateSQL(sql);
726 
727  String insertSQL = "INSERT";
728  if (DbType.SQLITE == tskDB.getDatabaseType()) {
729  insertSQL += " OR IGNORE";
730  }
731  insertSQL = insertSQL + " INTO " + tableName + " " + sql; // NON-NLS
732 
733  try {
734  return new CaseDbPreparedStatement(StatementType.INSERT, insertSQL, trans);
735  } catch (SQLException ex) {
736  throw new TskCoreException("Error creating insert prepared statement for query:\n" + insertSQL, ex);
737  }
738  }
739 
747  @Beta
748  public void insert(CaseDbPreparedStatement preparedStatement) throws TskCoreException {
749 
750  if (!preparedStatement.getType().equals(StatementType.INSERT)) {
751  throw new TskCoreException("CaseDbPreparedStatement has incorrect type for insert operation");
752  }
753 
754  try {
755  preparedStatement.getStatement().executeUpdate();
756  } catch (SQLException ex) {
757  throw new TskCoreException("Error inserting row in table " + "" + " with sql = "+ "", ex);
758  }
759  }
760 
769  public void delete(final String tableName, final String sql ) throws TskCoreException {
770  validateTableName(tableName);
771  validateSQL(sql);
772 
774  String deleteSQL = "DELETE FROM " + tableName + " " + sql; // NON-NLS
775  try (CaseDbConnection connection = tskDB.getConnection();
776  Statement statement = connection.createStatement();) {
777  statement.executeUpdate(deleteSQL);
778  } catch (SQLException ex) {
779  throw new TskCoreException("Error deleting row from table " + tableName, ex);
780  } finally {
782  }
783  }
784 
793  private void validateTableName(String tableName) throws TskCoreException {
794 
795  if (SleuthkitCase.getCoreTableNames().contains(tableName.toLowerCase())) {
796  throw new TskCoreException("Attempt to modify a core TSK table " + tableName);
797  }
798  if (tableName.toLowerCase().startsWith("tsk_")) {
799  throw new TskCoreException("Modifying tables with tsk_ prefix is not allowed. ");
800  }
801  }
802 
811  private void validateIndexName(String indexName) throws TskCoreException {
812 
813  if (indexName.isEmpty()) {
814  throw new TskCoreException("Invalid index name " + indexName);
815  }
816 
817  if (SleuthkitCase.getCoreIndexNames().contains(indexName.toLowerCase())) {
818  throw new TskCoreException("Attempt to modify a core TSK index " + indexName);
819  }
820  }
821 
829  private void validateSQL(String sql) throws TskCoreException {
830  /*
831  * TODO (JIRA-5950): Need SQL injection defense in CaseDbAccessManager
832  */
833  }
834 
838  private enum LockType {
839  READ,
840  WRITE,
841  NONE;
842  }
843 
847  private enum StatementType {
848  SELECT,
849  INSERT,
850  UPDATE;
851  }
852 
857  @Beta
858  public class CaseDbPreparedStatement implements AutoCloseable {
859 
860  private final CaseDbConnection connection;
861  private final PreparedStatement preparedStatement;
862  private final String originalSql;
863  private final LockType lockType;
864  private final StatementType type;
865 
887  private CaseDbPreparedStatement(StatementType type, String query, boolean isWriteLockRequired) throws SQLException, TskCoreException {
888  if (isWriteLockRequired) {
890  this.lockType = LockType.WRITE;
891  } else {
893  this.lockType = LockType.READ;
894  }
895  this.connection = tskDB.getConnection();
896  this.preparedStatement = connection.getPreparedStatement(query, Statement.NO_GENERATED_KEYS);
897  this.originalSql = query;
898  this.type = type;
899  }
900 
911  private CaseDbPreparedStatement(StatementType type, String query, CaseDbTransaction trans) throws SQLException, TskCoreException {
912  this.lockType = LockType.NONE;
913  this.connection = trans.getConnection();
914  this.preparedStatement = connection.getPreparedStatement(query, Statement.NO_GENERATED_KEYS);
915  this.originalSql = query;
916  this.type = type;
917  }
918 
924  private PreparedStatement getStatement() {
925  return preparedStatement;
926  }
927 
933  private StatementType getType() {
934  return type;
935  }
936 
942  private String getOriginalSql() {
943  return originalSql;
944  }
945 
951  public void reset() throws TskCoreException {
952  try {
953  preparedStatement.clearParameters();
954  } catch (SQLException ex) {
955  throw new TskCoreException("An error occurred while clearing parameters.", ex);
956  }
957  }
958 
967  public void setBoolean(int parameterIndex, boolean x) throws TskCoreException {
968  try {
969  preparedStatement.setBoolean(parameterIndex, x);
970  } catch (SQLException ex) {
971  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
972  }
973  }
974 
983  public void setByte(int parameterIndex, byte x) throws TskCoreException {
984  try {
985  preparedStatement.setByte(parameterIndex, x);
986  } catch (SQLException ex) {
987  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
988  }
989  }
990 
999  public void setInt(int parameterIndex, int x) throws TskCoreException {
1000  try {
1001  preparedStatement.setInt(parameterIndex, x);
1002  } catch (SQLException ex) {
1003  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1004  }
1005  }
1006 
1015  public void setLong(int parameterIndex, long x) throws TskCoreException {
1016  try {
1017  preparedStatement.setLong(parameterIndex, x);
1018  } catch (SQLException ex) {
1019  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1020  }
1021  }
1022 
1031  public void setDouble(int parameterIndex, double x) throws TskCoreException {
1032  try {
1033  preparedStatement.setDouble(parameterIndex, x);
1034  } catch (SQLException ex) {
1035  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1036  }
1037  }
1038 
1047  public void setString(int parameterIndex, String x) throws TskCoreException {
1048  try {
1049  preparedStatement.setString(parameterIndex, x);
1050  } catch (SQLException ex) {
1051  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1052  }
1053  }
1054 
1063  public void setDate(int parameterIndex, Date x) throws TskCoreException {
1064  try {
1065  preparedStatement.setDate(parameterIndex, x);
1066  } catch (SQLException ex) {
1067  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1068  }
1069  }
1070 
1079  public void setTime(int parameterIndex, Time x) throws TskCoreException {
1080  try {
1081  preparedStatement.setTime(parameterIndex, x);
1082  } catch (SQLException ex) {
1083  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1084  }
1085  }
1086 
1095  public void setTimestamp(int parameterIndex, Timestamp x) throws TskCoreException {
1096  try {
1097  preparedStatement.setTimestamp(parameterIndex, x);
1098  } catch (SQLException ex) {
1099  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1100  }
1101  }
1102 
1113  public void setObject(int parameterIndex, Object x) throws TskCoreException {
1114  try {
1115  preparedStatement.setObject(parameterIndex, x);
1116  } catch (SQLException ex) {
1117  throw new TskCoreException(MessageFormat.format("There was an error setting the value at index: {0} to {1}", parameterIndex, x), ex);
1118  }
1119  }
1120 
1121  @Override
1122  public void close() throws SQLException {
1123 
1124  // Don't close the statement/connection or release a lock if we were supplied a transaction.
1125  // Everything will be handled when the transaction is closed.
1126  if (lockType.equals(LockType.NONE)) {
1127  return;
1128  }
1129 
1130  connection.close();
1131  if (lockType.equals(LockType.WRITE)) {
1133  } else {
1135  }
1136  }
1137  }
1138 
1139 }
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)
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.