19 package org.sleuthkit.autopsy.centralrepository.datamodel;
21 import java.sql.Connection;
22 import java.sql.ResultSet;
23 import java.sql.SQLException;
24 import java.sql.Statement;
25 import java.util.Arrays;
26 import java.util.List;
28 import java.util.concurrent.locks.ReentrantReadWriteLock;
29 import java.util.logging.Level;
30 import org.apache.commons.dbcp2.BasicDataSource;
41 final class SqliteEamDb
extends AbstractSqlEamDb {
43 private final static Logger LOGGER = Logger.getLogger(SqliteEamDb.class.getName());
45 private static SqliteEamDb instance;
47 private BasicDataSource connectionPool = null;
49 private final SqliteEamDbSettings dbSettings;
53 private final ReentrantReadWriteLock rwLock =
new ReentrantReadWriteLock(
true);
63 public synchronized static SqliteEamDb getInstance() throws EamDbException {
64 if (instance == null) {
65 instance =
new SqliteEamDb();
77 private SqliteEamDb() throws EamDbException {
78 dbSettings =
new SqliteEamDbSettings();
79 bulkArtifactsThreshold = dbSettings.getBulkThreshold();
83 public void shutdownConnections() throws EamDbException {
86 if (null != connectionPool) {
87 connectionPool.close();
88 connectionPool = null;
92 }
catch (SQLException ex) {
93 throw new EamDbException(
"Failed to close existing database connections.", ex);
98 public void updateSettings() {
100 dbSettings.loadSettings();
101 bulkArtifactsThreshold = dbSettings.getBulkThreshold();
106 public void saveSettings() {
107 synchronized (
this) {
108 dbSettings.saveSettings();
113 public void reset() throws EamDbException {
115 acquireExclusiveLock();
117 Connection conn = connect();
121 Statement dropContent = conn.createStatement();
122 dropContent.executeUpdate(
"DELETE FROM organizations");
123 dropContent.executeUpdate(
"DELETE FROM cases");
124 dropContent.executeUpdate(
"DELETE FROM data_sources");
125 dropContent.executeUpdate(
"DELETE FROM reference_sets");
126 dropContent.executeUpdate(
"DELETE FROM artifact_types");
127 dropContent.executeUpdate(
"DELETE FROM db_info");
129 String instancesTemplate =
"DELETE FROM %s_instances";
130 String referencesTemplate =
"DELETE FROM global_files";
131 for (CorrelationAttributeInstance.Type type : defaultCorrelationTypes) {
132 dropContent.executeUpdate(String.format(instancesTemplate, type.getDbTableName()));
134 if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
135 dropContent.executeUpdate(String.format(referencesTemplate, type.getDbTableName()));
139 dropContent.executeUpdate(
"VACUUM");
140 }
catch (SQLException ex) {
141 LOGGER.log(Level.WARNING,
"Failed to reset database.", ex);
143 EamDbUtil.closeConnection(conn);
146 dbSettings.insertDefaultDatabaseContent();
148 releaseExclusiveLock();
156 private void setupConnectionPool() throws EamDbException {
158 if (dbSettings.dbFileExists() ==
false) {
159 throw new EamDbException(
"Central repository database missing");
162 connectionPool =
new BasicDataSource();
163 connectionPool.setDriverClassName(dbSettings.getDriver());
164 connectionPool.setUrl(dbSettings.getConnectionURL());
167 connectionPool.setInitialSize(50);
168 connectionPool.setMaxTotal(-1);
169 connectionPool.setMaxIdle(-1);
170 connectionPool.setMaxWaitMillis(1000);
171 connectionPool.setValidationQuery(dbSettings.getValidationQuery());
172 connectionPool.setConnectionInitSqls(Arrays.asList(
"PRAGMA foreign_keys = ON"));
183 protected Connection connect() throws EamDbException {
184 synchronized (
this) {
185 if (!EamDb.isEnabled()) {
186 throw new EamDbException(
"Central Repository module is not enabled");
189 if (connectionPool == null) {
190 setupConnectionPool();
194 return connectionPool.getConnection();
195 }
catch (SQLException ex) {
196 throw new EamDbException(
"Error getting connection from connection pool.", ex);
202 protected String getConflictClause() {
216 public void newDbInfo(String name, String value)
throws EamDbException {
218 acquireExclusiveLock();
219 super.newDbInfo(name, value);
221 releaseExclusiveLock();
235 public String getDbInfo(String name)
throws EamDbException {
238 return super.getDbInfo(name);
253 public void updateDbInfo(String name, String value)
throws EamDbException {
255 acquireExclusiveLock();
256 super.updateDbInfo(name, value);
258 releaseExclusiveLock();
268 public CorrelationCase newCase(Case autopsyCase)
throws EamDbException {
270 acquireExclusiveLock();
271 return super.newCase(autopsyCase);
273 releaseExclusiveLock();
278 public void addDataSourceObjectId(
int rowId,
long dataSourceObjectId)
throws EamDbException{
280 acquireExclusiveLock();
281 super.addDataSourceObjectId(rowId, dataSourceObjectId);
283 releaseExclusiveLock();
295 public CorrelationCase newCase(CorrelationCase eamCase)
throws EamDbException {
297 acquireExclusiveLock();
298 return super.newCase(eamCase);
300 releaseExclusiveLock();
310 public void updateCase(CorrelationCase eamCase)
throws EamDbException {
312 acquireExclusiveLock();
313 super.updateCase(eamCase);
315 releaseExclusiveLock();
327 public CorrelationCase getCaseByUUID(String caseUUID)
throws EamDbException {
330 return super.getCaseByUUID(caseUUID);
344 public CorrelationCase getCaseById(
int caseId)
throws EamDbException {
347 return super.getCaseById(caseId);
360 public List<CorrelationCase> getCases() throws EamDbException {
363 return super.getCases();
375 public CorrelationDataSource newDataSource(CorrelationDataSource eamDataSource)
throws EamDbException {
377 acquireExclusiveLock();
378 return super.newDataSource(eamDataSource);
380 releaseExclusiveLock();
394 public CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long caseDbDataSourceId)
throws EamDbException {
397 return super.getDataSource(correlationCase, caseDbDataSourceId);
413 public CorrelationDataSource getDataSourceById(CorrelationCase correlationCase,
int dataSourceId)
throws EamDbException {
416 return super.getDataSourceById(correlationCase, dataSourceId);
428 public List<CorrelationDataSource> getDataSources() throws EamDbException {
431 return super.getDataSources();
444 public void addArtifactInstance(CorrelationAttributeInstance eamArtifact)
throws EamDbException {
446 acquireExclusiveLock();
447 super.addArtifactInstance(eamArtifact);
449 releaseExclusiveLock();
463 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws EamDbException, CorrelationAttributeNormalizationException {
466 return super.getArtifactInstancesByTypeValue(aType, value);
484 public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttributeInstance.Type aType, String filePath)
throws EamDbException {
487 return super.getArtifactInstancesByPath(aType, filePath);
506 public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws EamDbException, CorrelationAttributeNormalizationException {
509 return super.getCountArtifactInstancesByTypeValue(aType, value);
516 public int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
throws EamDbException, CorrelationAttributeNormalizationException {
519 return super.getFrequencyPercentage(corAttr);
538 public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws EamDbException, CorrelationAttributeNormalizationException {
541 return super.getCountUniqueCaseDataSourceTuplesHavingTypeValue(aType, value);
548 public Long getCountUniqueDataSources() throws EamDbException {
551 return super.getCountUniqueDataSources();
569 public Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource)
throws EamDbException {
572 return super.getCountArtifactInstancesByCaseDataSource(correlationDataSource);
583 public void commitAttributeInstancesBulk() throws EamDbException {
585 acquireExclusiveLock();
586 super.commitAttributeInstancesBulk();
588 releaseExclusiveLock();
596 public void bulkInsertCases(List<CorrelationCase> cases)
throws EamDbException {
598 acquireExclusiveLock();
599 super.bulkInsertCases(cases);
601 releaseExclusiveLock();
616 public void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
618 acquireExclusiveLock();
619 super.setAttributeInstanceKnownStatus(eamArtifact, knownStatus);
621 releaseExclusiveLock();
635 public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws EamDbException, CorrelationAttributeNormalizationException {
638 return super.getArtifactInstancesKnownBad(aType, value);
656 public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType) throws EamDbException {
659 return super.getArtifactInstancesKnownBad(aType);
674 public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws EamDbException, CorrelationAttributeNormalizationException {
677 return super.getCountArtifactInstancesKnownBad(aType, value);
696 public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws EamDbException, CorrelationAttributeNormalizationException {
699 return super.getListCasesHavingArtifactInstancesKnownBad(aType, value);
713 public void deleteReferenceSet(
int referenceSetID)
throws EamDbException {
715 acquireExclusiveLock();
716 super.deleteReferenceSet(referenceSetID);
718 releaseExclusiveLock();
732 public boolean isValueInReferenceSet(String value,
int referenceSetID,
int correlationTypeID)
throws EamDbException, CorrelationAttributeNormalizationException {
735 return super.isValueInReferenceSet(value, referenceSetID, correlationTypeID);
750 public void processInstanceTable(CorrelationAttributeInstance.Type type, InstanceTableCallback instanceTableCallback)
throws EamDbException {
753 super.processInstanceTable(type, instanceTableCallback);
768 public void processInstanceTableWhere(CorrelationAttributeInstance.Type type, String whereClause, InstanceTableCallback instanceTableCallback)
throws EamDbException {
771 super.processInstanceTableWhere(type, whereClause, instanceTableCallback);
790 public boolean referenceSetExists(String referenceSetName, String version)
throws EamDbException {
793 return super.referenceSetExists(referenceSetName, version);
808 public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value)
throws EamDbException, CorrelationAttributeNormalizationException {
811 return super.isArtifactKnownBadByReference(aType, value);
827 public EamOrganization newOrganization(EamOrganization eamOrg)
throws EamDbException {
829 acquireExclusiveLock();
830 return super.newOrganization(eamOrg);
832 releaseExclusiveLock();
844 public List<EamOrganization> getOrganizations() throws EamDbException {
847 return super.getOrganizations();
863 public EamOrganization getOrganizationByID(
int orgID)
throws EamDbException {
866 return super.getOrganizationByID(orgID);
873 public void updateOrganization(EamOrganization updatedOrganization)
throws EamDbException {
875 acquireExclusiveLock();
876 super.updateOrganization(updatedOrganization);
878 releaseExclusiveLock();
883 public void deleteOrganization(EamOrganization organizationToDelete)
throws EamDbException {
885 acquireExclusiveLock();
886 super.deleteOrganization(organizationToDelete);
888 releaseExclusiveLock();
902 public int newReferenceSet(EamGlobalSet eamGlobalSet)
throws EamDbException {
904 acquireExclusiveLock();
905 return super.newReferenceSet(eamGlobalSet);
907 releaseExclusiveLock();
921 public EamGlobalSet getReferenceSetByID(
int referenceSetID)
throws EamDbException {
924 return super.getReferenceSetByID(referenceSetID);
940 public List<EamGlobalSet> getAllReferenceSets(CorrelationAttributeInstance.Type correlationType) throws EamDbException {
943 return super.getAllReferenceSets(correlationType);
959 public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttributeInstance.Type correlationType) throws EamDbException {
961 acquireExclusiveLock();
962 super.addReferenceInstance(eamGlobalFileInstance, correlationType);
964 releaseExclusiveLock();
974 public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttributeInstance.Type contentType) throws EamDbException {
976 acquireExclusiveLock();
977 super.bulkInsertReferenceTypeEntries(globalInstances, contentType);
979 releaseExclusiveLock();
994 public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue)
throws EamDbException, CorrelationAttributeNormalizationException {
997 return super.getReferenceInstancesByTypeValue(aType, aValue);
1013 public int newCorrelationType(CorrelationAttributeInstance.Type newType) throws EamDbException {
1015 acquireExclusiveLock();
1016 return super.newCorrelationType(newType);
1018 releaseExclusiveLock();
1032 public List<CorrelationAttributeInstance.Type> getDefinedCorrelationTypes() throws EamDbException {
1034 acquireSharedLock();
1035 return super.getDefinedCorrelationTypes();
1037 releaseSharedLock();
1051 public List<CorrelationAttributeInstance.Type> getEnabledCorrelationTypes() throws EamDbException {
1053 acquireSharedLock();
1054 return super.getEnabledCorrelationTypes();
1056 releaseSharedLock();
1070 public List<CorrelationAttributeInstance.Type> getSupportedCorrelationTypes() throws EamDbException {
1072 acquireSharedLock();
1073 return super.getSupportedCorrelationTypes();
1075 releaseSharedLock();
1087 public void updateCorrelationType(CorrelationAttributeInstance.Type aType) throws EamDbException {
1089 acquireExclusiveLock();
1090 super.updateCorrelationType(aType);
1092 releaseExclusiveLock();
1106 public CorrelationAttributeInstance.Type getCorrelationTypeById(
int typeId)
throws EamDbException {
1108 acquireSharedLock();
1109 return super.getCorrelationTypeById(typeId);
1111 releaseSharedLock();
1121 public void upgradeSchema() throws EamDbException, SQLException {
1123 acquireExclusiveLock();
1124 super.upgradeSchema();
1126 releaseExclusiveLock();
1142 public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException {
1152 private void acquireExclusiveLock() {
1153 rwLock.writeLock().lock();
1161 private void releaseExclusiveLock() {
1162 rwLock.writeLock().unlock();
1170 private void acquireSharedLock() {
1171 rwLock.readLock().lock();
1179 private void releaseSharedLock() {
1180 rwLock.readLock().unlock();
1184 boolean doesColumnExist(Connection conn, String tableName, String columnName)
throws SQLException {
1185 final String tableInfoQueryTemplate =
"PRAGMA table_info(%s)";
1186 ResultSet resultSet = null;
1187 Statement statement = null;
1188 boolean columnExists =
false;
1190 statement = conn.createStatement();
1191 resultSet = statement.executeQuery(String.format(tableInfoQueryTemplate, tableName));
1192 while (resultSet.next()) {
1194 if (resultSet.getString(2).equals(columnName)) {
1195 columnExists =
true;
1200 EamDbUtil.closeResultSet(resultSet);
1201 EamDbUtil.closeStatement(statement);
1203 return columnExists;