19 package org.sleuthkit.datamodel;
22 import java.io.UnsupportedEncodingException;
23 import java.net.URLEncoder;
24 import java.sql.Connection;
25 import java.sql.DriverManager;
26 import java.sql.SQLException;
27 import java.sql.Statement;
28 import java.util.Properties;
29 import java.util.logging.Logger;
30 import java.util.logging.Level;
37 class CaseDatabaseFactory {
39 private static final Logger logger = Logger.getLogger(CaseDatabaseFactory.class.getName());
40 private final SQLHelper dbQueryHelper;
41 private final DbCreationHelper dbCreationHelper;
48 CaseDatabaseFactory(String dbPath) {
49 this.dbQueryHelper =
new SQLiteHelper();
50 this.dbCreationHelper =
new SQLiteDbCreationHelper(dbPath);
63 CaseDatabaseFactory(String caseName, CaseDbConnectionInfo info) {
64 this.dbQueryHelper =
new PostgreSQLHelper();
65 this.dbCreationHelper =
new PostgreSQLDbCreationHelper(caseName, info);
74 void createCaseDatabase() throws TskCoreException {
84 private void createDatabase() throws TskCoreException {
85 dbCreationHelper.createDatabase();
93 private void initializeSchema() throws TskCoreException {
94 try (Connection conn = dbCreationHelper.getConnection()) {
96 dbCreationHelper.performPreInitialization(conn);
103 dbCreationHelper.performPostTableInitialization(conn);
107 }
catch (SQLException ex) {
108 throw new TskCoreException(
"Error initializing case database", ex);
119 private void addDbInfo(Connection conn)
throws TskCoreException {
120 CaseDbSchemaVersionNumber version = SleuthkitCase.CURRENT_DB_SCHEMA_VERSION;
121 long tskVersionNum = SleuthkitJNI.getSleuthkitVersion();
123 try (Statement stmt = conn.createStatement()) {
124 stmt.execute(
"CREATE TABLE tsk_db_info (schema_ver INTEGER, tsk_ver INTEGER, schema_minor_ver INTEGER)");
125 stmt.execute(
"INSERT INTO tsk_db_info (schema_ver, tsk_ver, schema_minor_ver) VALUES (" +
126 version.getMajor() +
", " + tskVersionNum +
", " + version.getMinor() +
");");
128 stmt.execute(
"CREATE TABLE tsk_db_info_extended (name TEXT PRIMARY KEY, value TEXT NOT NULL);");
129 stmt.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('TSK_VERSION', '" + tskVersionNum +
"');");
130 stmt.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('SCHEMA_MAJOR_VERSION', '" + version.getMajor() +
"');");
131 stmt.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('SCHEMA_MINOR_VERSION', '" + version.getMinor() +
"');");
132 stmt.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('CREATION_SCHEMA_MAJOR_VERSION', '" + version.getMajor() +
"');");
133 stmt.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('CREATION_SCHEMA_MINOR_VERSION', '" + version.getMinor() +
"');");
134 }
catch (SQLException ex) {
135 throw new TskCoreException(
"Error initializing db_info tables", ex);
146 private void addTables(Connection conn)
throws TskCoreException {
147 try (Statement stmt = conn.createStatement()) {
148 createFileTables(stmt);
149 createArtifactTables(stmt);
150 createTagTables(stmt);
151 createIngestTables(stmt);
152 createAccountTables(stmt);
153 createEventTables(stmt);
154 }
catch (SQLException ex) {
155 throw new TskCoreException(
"Error initializing tables", ex);
159 private void createFileTables(Statement stmt)
throws SQLException {
161 stmt.execute(
"CREATE TABLE tsk_objects (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, par_obj_id " + dbQueryHelper.getBigIntType()
162 +
", type INTEGER NOT NULL, UNIQUE (obj_id), FOREIGN KEY (par_obj_id) REFERENCES tsk_objects (obj_id) ON DELETE CASCADE)");
164 stmt.execute(
"CREATE TABLE tsk_image_info (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, type INTEGER, ssize INTEGER, "
165 +
"tzone TEXT, size " + dbQueryHelper.getBigIntType() +
", md5 TEXT, sha1 TEXT, sha256 TEXT, display_name TEXT, "
166 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
168 stmt.execute(
"CREATE TABLE tsk_image_names (obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, name TEXT NOT NULL, "
169 +
"sequence INTEGER NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
171 stmt.execute(
"CREATE TABLE tsk_vs_info (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, vs_type INTEGER NOT NULL, "
172 +
"img_offset " + dbQueryHelper.getBigIntType() +
" NOT NULL, block_size " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
173 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
175 stmt.execute(
"CREATE TABLE tsk_vs_parts (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
176 +
"addr " + dbQueryHelper.getBigIntType() +
" NOT NULL, start " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
177 +
"length " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
178 + dbQueryHelper.getVSDescColName() +
" TEXT, "
179 +
"flags INTEGER NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE);");
181 stmt.execute(
"CREATE TABLE tsk_pool_info (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
182 +
"pool_type INTEGER NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE);");
184 stmt.execute(
"CREATE TABLE data_source_info (obj_id " + dbQueryHelper.getBigIntType() +
" PRIMARY KEY, device_id TEXT NOT NULL, "
185 +
"time_zone TEXT NOT NULL, acquisition_details TEXT, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
187 stmt.execute(
"CREATE TABLE tsk_fs_info (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
188 +
"data_source_obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
189 +
"img_offset " + dbQueryHelper.getBigIntType() +
" NOT NULL, fs_type INTEGER NOT NULL, "
190 +
"block_size " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
191 +
"block_count " + dbQueryHelper.getBigIntType() +
" NOT NULL, root_inum " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
192 +
"first_inum " + dbQueryHelper.getBigIntType() +
" NOT NULL, last_inum " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
193 +
"display_name TEXT, "
194 +
"FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id) ON DELETE CASCADE, "
195 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
197 stmt.execute(
"CREATE TABLE tsk_files (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
198 +
"fs_obj_id " + dbQueryHelper.getBigIntType() +
", data_source_obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
199 +
"attr_type INTEGER, attr_id INTEGER, "
200 +
"name TEXT NOT NULL, meta_addr " + dbQueryHelper.getBigIntType() +
", meta_seq " + dbQueryHelper.getBigIntType() +
", "
201 +
"type INTEGER, has_layout INTEGER, has_path INTEGER, "
202 +
"dir_type INTEGER, meta_type INTEGER, dir_flags INTEGER, meta_flags INTEGER, size " + dbQueryHelper.getBigIntType() +
", "
203 +
"ctime " + dbQueryHelper.getBigIntType() +
", "
204 +
"crtime " + dbQueryHelper.getBigIntType() +
", atime " + dbQueryHelper.getBigIntType() +
", "
205 +
"mtime " + dbQueryHelper.getBigIntType() +
", mode INTEGER, uid INTEGER, gid INTEGER, md5 TEXT, known INTEGER, "
206 +
"parent_path TEXT, mime_type TEXT, extension TEXT, "
207 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
208 +
"FOREIGN KEY(fs_obj_id) REFERENCES tsk_fs_info(obj_id) ON DELETE CASCADE, "
209 +
"FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id) ON DELETE CASCADE)");
211 stmt.execute(
"CREATE TABLE file_encoding_types (encoding_type INTEGER PRIMARY KEY, name TEXT NOT NULL)");
213 stmt.execute(
"CREATE TABLE tsk_files_path (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, path TEXT NOT NULL, "
214 +
"encoding_type INTEGER NOT NULL, FOREIGN KEY(encoding_type) references file_encoding_types(encoding_type), "
215 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
217 stmt.execute(
"CREATE TABLE tsk_files_derived (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
218 +
"derived_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, rederive TEXT, "
219 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
221 stmt.execute(
"CREATE TABLE tsk_files_derived_method (derived_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
222 +
"tool_name TEXT NOT NULL, tool_version TEXT NOT NULL, other TEXT)");
224 stmt.execute(
"CREATE TABLE tsk_file_layout (obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
225 +
"byte_start " + dbQueryHelper.getBigIntType() +
" NOT NULL, byte_len " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
226 +
"sequence INTEGER NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE);");
228 stmt.execute(
"CREATE TABLE reports (obj_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, path TEXT NOT NULL, "
229 +
"crtime INTEGER NOT NULL, src_module_name TEXT NOT NULL, report_name TEXT NOT NULL, "
230 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE);");
233 private void createArtifactTables(Statement stmt)
throws SQLException {
234 stmt.execute(
"CREATE TABLE blackboard_artifact_types (artifact_type_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
235 +
"type_name TEXT NOT NULL, display_name TEXT)");
237 stmt.execute(
"CREATE TABLE blackboard_attribute_types (attribute_type_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
238 +
"type_name TEXT NOT NULL, display_name TEXT, value_type INTEGER NOT NULL)");
240 stmt.execute(
"CREATE TABLE review_statuses (review_status_id INTEGER PRIMARY KEY, "
241 +
"review_status_name TEXT NOT NULL, "
242 +
"display_name TEXT NOT NULL)");
244 stmt.execute(
"CREATE TABLE blackboard_artifacts (artifact_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
245 +
"obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
246 +
"artifact_obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
247 +
"data_source_obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
248 +
"artifact_type_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
249 +
"review_status_id INTEGER NOT NULL, "
250 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
251 +
"FOREIGN KEY(artifact_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
252 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
253 +
"FOREIGN KEY(artifact_type_id) REFERENCES blackboard_artifact_types(artifact_type_id), "
254 +
"FOREIGN KEY(review_status_id) REFERENCES review_statuses(review_status_id))");
260 stmt.execute(
"CREATE TABLE blackboard_attributes (artifact_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
261 +
"artifact_type_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
262 +
"source TEXT, context TEXT, attribute_type_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
263 +
"value_type INTEGER NOT NULL, value_byte " + dbQueryHelper.getBlobType() +
", "
264 +
"value_text TEXT, value_int32 INTEGER, value_int64 " + dbQueryHelper.getBigIntType() +
", value_double NUMERIC(20, 10), "
265 +
"FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id) ON DELETE CASCADE, "
266 +
"FOREIGN KEY(artifact_type_id) REFERENCES blackboard_artifact_types(artifact_type_id), "
267 +
"FOREIGN KEY(attribute_type_id) REFERENCES blackboard_attribute_types(attribute_type_id))");
270 private void createTagTables(Statement stmt)
throws SQLException {
271 stmt.execute(
"CREATE TABLE tsk_tag_sets (tag_set_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, name TEXT UNIQUE)");
272 stmt.execute(
"CREATE TABLE tag_names (tag_name_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, display_name TEXT UNIQUE, "
273 +
"description TEXT NOT NULL, color TEXT NOT NULL, knownStatus INTEGER NOT NULL,"
274 +
" tag_set_id " + dbQueryHelper.getBigIntType() +
", rank INTEGER, FOREIGN KEY(tag_set_id) REFERENCES tsk_tag_sets(tag_set_id) ON DELETE SET NULL)");
276 stmt.execute(
"CREATE TABLE tsk_examiners (examiner_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
277 +
"login_name TEXT NOT NULL, display_name TEXT, UNIQUE(login_name))");
279 stmt.execute(
"CREATE TABLE content_tags (tag_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
280 +
"obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, tag_name_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
281 +
"comment TEXT NOT NULL, begin_byte_offset " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
282 +
"end_byte_offset " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
283 +
"examiner_id " + dbQueryHelper.getBigIntType() +
", "
284 +
"FOREIGN KEY(examiner_id) REFERENCES tsk_examiners(examiner_id) ON DELETE CASCADE, "
285 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
286 +
"FOREIGN KEY(tag_name_id) REFERENCES tag_names(tag_name_id) ON DELETE CASCADE)");
288 stmt.execute(
"CREATE TABLE blackboard_artifact_tags (tag_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
289 +
"artifact_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, tag_name_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
290 +
"comment TEXT NOT NULL, examiner_id " + dbQueryHelper.getBigIntType() +
", "
291 +
"FOREIGN KEY(examiner_id) REFERENCES tsk_examiners(examiner_id) ON DELETE CASCADE, "
292 +
"FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id) ON DELETE CASCADE, "
293 +
"FOREIGN KEY(tag_name_id) REFERENCES tag_names(tag_name_id) ON DELETE CASCADE)");
302 private void addIndexes(Connection conn)
throws TskCoreException {
303 try (Statement stmt = conn.createStatement()) {
305 stmt.execute(
"CREATE INDEX parObjId ON tsk_objects(par_obj_id)");
308 stmt.execute(
"CREATE INDEX layout_objID ON tsk_file_layout(obj_id)");
311 stmt.execute(
"CREATE INDEX artifact_objID ON blackboard_artifacts(obj_id)");
312 stmt.execute(
"CREATE INDEX artifact_artifact_objID ON blackboard_artifacts(artifact_obj_id)");
313 stmt.execute(
"CREATE INDEX artifact_typeID ON blackboard_artifacts(artifact_type_id)");
314 stmt.execute(
"CREATE INDEX attrsArtifactID ON blackboard_attributes(artifact_id)");
317 stmt.execute(
"CREATE INDEX mime_type ON tsk_files(dir_type,mime_type,type)");
318 stmt.execute(
"CREATE INDEX file_extension ON tsk_files(extension)");
321 stmt.execute(
"CREATE INDEX relationships_account1 ON account_relationships(account1_id)");
322 stmt.execute(
"CREATE INDEX relationships_account2 ON account_relationships(account2_id)");
323 stmt.execute(
"CREATE INDEX relationships_relationship_source_obj_id ON account_relationships(relationship_source_obj_id)");
324 stmt.execute(
"CREATE INDEX relationships_date_time ON account_relationships(date_time)");
325 stmt.execute(
"CREATE INDEX relationships_relationship_type ON account_relationships(relationship_type)");
326 stmt.execute(
"CREATE INDEX relationships_data_source_obj_id ON account_relationships(data_source_obj_id)");
329 stmt.execute(
"CREATE INDEX events_data_source_obj_id ON tsk_event_descriptions(data_source_obj_id)");
330 stmt.execute(
"CREATE INDEX events_content_obj_id ON tsk_event_descriptions(content_obj_id)");
331 stmt.execute(
"CREATE INDEX events_artifact_id ON tsk_event_descriptions(artifact_id)");
332 stmt.execute(
"CREATE INDEX events_sub_type_time ON tsk_events(event_type_id, time)");
333 stmt.execute(
"CREATE INDEX events_time ON tsk_events(time)");
334 }
catch (SQLException ex) {
335 throw new TskCoreException(
"Error initializing db_info tables", ex);
339 private void createIngestTables(Statement stmt)
throws SQLException {
340 stmt.execute(
"CREATE TABLE ingest_module_types (type_id INTEGER PRIMARY KEY, type_name TEXT NOT NULL)");
342 stmt.execute(
"CREATE TABLE ingest_job_status_types (type_id INTEGER PRIMARY KEY, type_name TEXT NOT NULL)");
344 stmt.execute(
"CREATE TABLE ingest_modules (ingest_module_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
345 +
"display_name TEXT NOT NULL, unique_name TEXT UNIQUE NOT NULL, type_id INTEGER NOT NULL, "
346 +
"version TEXT NOT NULL, FOREIGN KEY(type_id) REFERENCES ingest_module_types(type_id) ON DELETE CASCADE);");
348 stmt.execute(
"CREATE TABLE ingest_jobs (ingest_job_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
349 +
"obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, host_name TEXT NOT NULL, "
350 +
"start_date_time " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
351 +
"end_date_time " + dbQueryHelper.getBigIntType() +
" NOT NULL, status_id INTEGER NOT NULL, "
352 +
"settings_dir TEXT, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
353 +
"FOREIGN KEY(status_id) REFERENCES ingest_job_status_types(type_id) ON DELETE CASCADE);");
355 stmt.execute(
"CREATE TABLE ingest_job_modules (ingest_job_id INTEGER, ingest_module_id INTEGER, "
356 +
"pipeline_position INTEGER, PRIMARY KEY(ingest_job_id, ingest_module_id), "
357 +
"FOREIGN KEY(ingest_job_id) REFERENCES ingest_jobs(ingest_job_id) ON DELETE CASCADE, "
358 +
"FOREIGN KEY(ingest_module_id) REFERENCES ingest_modules(ingest_module_id) ON DELETE CASCADE);");
361 private void createAccountTables(Statement stmt)
throws SQLException {
362 stmt.execute(
"CREATE TABLE account_types (account_type_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
363 +
"type_name TEXT UNIQUE NOT NULL, display_name TEXT NOT NULL)");
365 stmt.execute(
"CREATE TABLE accounts (account_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
366 +
"account_type_id INTEGER NOT NULL, account_unique_identifier TEXT NOT NULL, "
367 +
"UNIQUE(account_type_id, account_unique_identifier), "
368 +
"FOREIGN KEY(account_type_id) REFERENCES account_types(account_type_id))");
370 stmt.execute(
"CREATE TABLE account_relationships (relationship_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
371 +
"account1_id INTEGER NOT NULL, account2_id INTEGER NOT NULL, "
372 +
"relationship_source_obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
373 +
"date_time " + dbQueryHelper.getBigIntType() +
", relationship_type INTEGER NOT NULL, "
374 +
"data_source_obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
375 +
"UNIQUE(account1_id, account2_id, relationship_source_obj_id), "
376 +
"FOREIGN KEY(account1_id) REFERENCES accounts(account_id), "
377 +
"FOREIGN KEY(account2_id) REFERENCES accounts(account_id), "
378 +
"FOREIGN KEY(relationship_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
379 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
382 private void createEventTables(Statement stmt)
throws SQLException {
383 stmt.execute(
"CREATE TABLE tsk_event_types ("
384 +
" event_type_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY,"
385 +
" display_name TEXT UNIQUE NOT NULL , "
386 +
" super_type_id INTEGER REFERENCES tsk_event_types(event_type_id) )");
388 stmt.execute(
"INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(0, 'Event Types', null)");
389 stmt.execute(
"INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(1, 'File System', 0)");
390 stmt.execute(
"INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(2, 'Web Activity', 0)");
391 stmt.execute(
"INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(3, 'Misc Types', 0)");
392 stmt.execute(
"INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(4, 'Modified', 1)");
393 stmt.execute(
"INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(5, 'Accessed', 1)");
394 stmt.execute(
"INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(6, 'Created', 1)");
395 stmt.execute(
"INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(7, 'Changed', 1)");
409 "CREATE TABLE tsk_event_descriptions ( "
410 +
" event_description_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
411 +
" full_description TEXT NOT NULL, "
412 +
" med_description TEXT, "
413 +
" short_description TEXT,"
414 +
" data_source_obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
415 +
" content_obj_id " + dbQueryHelper.getBigIntType() +
" NOT NULL, "
416 +
" artifact_id " + dbQueryHelper.getBigIntType() +
", "
417 +
" hash_hit INTEGER NOT NULL, "
418 +
" tagged INTEGER NOT NULL, "
419 +
" FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id) ON DELETE CASCADE, "
420 +
" FOREIGN KEY(content_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
421 +
" FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id) ON DELETE CASCADE,"
422 +
" UNIQUE (full_description, content_obj_id, artifact_id))");
425 "CREATE TABLE tsk_events ("
426 +
" event_id " + dbQueryHelper.getPrimaryKey() +
" PRIMARY KEY, "
427 +
" event_type_id " + dbQueryHelper.getBigIntType() +
" NOT NULL REFERENCES tsk_event_types(event_type_id) ,"
428 +
" event_description_id " + dbQueryHelper.getBigIntType() +
" NOT NULL REFERENCES tsk_event_descriptions(event_description_id) ON DELETE CASCADE ,"
429 +
" time " + dbQueryHelper.getBigIntType() +
" NOT NULL , "
430 +
" UNIQUE (event_type_id, event_description_id, time))");
436 private abstract class DbCreationHelper {
443 abstract void createDatabase() throws TskCoreException;
450 abstract Connection getConnection() throws TskCoreException;
460 abstract
void performPreInitialization(Connection conn) throws TskCoreException;
468 abstract
void performPostTableInitialization(Connection conn) throws TskCoreException;
474 private class PostgreSQLDbCreationHelper extends DbCreationHelper {
476 private final static String JDBC_BASE_URI =
"jdbc:postgresql://";
477 private final static String JDBC_DRIVER =
"org.postgresql.Driver";
479 final private String caseName;
480 final private CaseDbConnectionInfo info;
482 PostgreSQLDbCreationHelper(String caseName, CaseDbConnectionInfo info) {
483 this.caseName = caseName;
488 void createDatabase() throws TskCoreException{
489 try(Connection conn = getPostgresConnection();
490 Statement stmt = conn.createStatement()) {
491 stmt.execute(
"CREATE DATABASE \"" + caseName +
"\" WITH ENCODING='UTF8'");
492 }
catch (SQLException ex) {
493 throw new TskCoreException(
"Error creating PostgreSQL case " + caseName, ex);
498 Connection getConnection() throws TskCoreException {
499 return getConnection(caseName);
507 Connection getPostgresConnection() throws TskCoreException {
508 return getConnection(
"postgres");
518 Connection getConnection(String databaseName)
throws TskCoreException {
519 String encodedDbName;
521 encodedDbName = URLEncoder.encode(databaseName,
"UTF-8");
522 }
catch (UnsupportedEncodingException ex) {
524 logger.log(Level.WARNING,
"Error encoding database name " + databaseName, ex);
525 encodedDbName = databaseName;
528 StringBuilder url =
new StringBuilder();
529 url.append(JDBC_BASE_URI)
530 .append(info.getHost())
532 .append(encodedDbName);
536 Properties props =
new Properties();
537 props.setProperty(
"user", info.getUserName());
538 props.setProperty(
"password", info.getPassword());
540 Class.forName(JDBC_DRIVER);
541 conn = DriverManager.getConnection(url.toString(), props);
542 }
catch (ClassNotFoundException | SQLException ex) {
543 throw new TskCoreException(
"Failed to acquire ephemeral connection to PostgreSQL database " + databaseName, ex);
549 void performPreInitialization(Connection conn)
throws TskCoreException {
554 void performPostTableInitialization(Connection conn)
throws TskCoreException {
555 try (Statement stmt = conn.createStatement()) {
556 stmt.execute(
"ALTER SEQUENCE blackboard_artifacts_artifact_id_seq minvalue -9223372036854775808 restart with -9223372036854775808");
557 }
catch (SQLException ex) {
558 throw new TskCoreException(
"Error altering artifact ID sequence", ex);
566 private class SQLiteDbCreationHelper
extends DbCreationHelper {
568 private final static String PRAGMA_SYNC_OFF =
"PRAGMA synchronous = OFF";
569 private final static String PRAGMA_READ_UNCOMMITTED_TRUE =
"PRAGMA read_uncommitted = True";
570 private final static String PRAGMA_ENCODING_UTF8 =
"PRAGMA encoding = 'UTF-8'";
571 private final static String PRAGMA_PAGE_SIZE_4096 =
"PRAGMA page_size = 4096";
572 private final static String PRAGMA_FOREIGN_KEYS_ON =
"PRAGMA foreign_keys = ON";
574 private final static String JDBC_DRIVER =
"org.sqlite.JDBC";
575 private final static String JDBC_BASE_URI =
"jdbc:sqlite:";
579 SQLiteDbCreationHelper(String dbPath) {
580 this.dbPath = dbPath;
584 void createDatabase() throws TskCoreException {
587 File dbFile =
new File(dbPath);
588 if (dbFile.exists()) {
589 throw new TskCoreException(
"Case database already exists : " + dbPath);
592 if (dbFile.getParentFile() != null && !dbFile.getParentFile().exists()) {
593 throw new TskCoreException(
"Case database folder does not exist : " + dbFile.getParent());
598 Connection getConnection() throws TskCoreException {
600 StringBuilder url =
new StringBuilder();
601 url.append(JDBC_BASE_URI)
606 Class.forName(JDBC_DRIVER);
607 conn = DriverManager.getConnection(url.toString());
608 }
catch (ClassNotFoundException | SQLException ex) {
609 throw new TskCoreException(
"Failed to acquire ephemeral connection SQLite database " + dbPath, ex);
615 void performPreInitialization(Connection conn)
throws TskCoreException {
616 try (Statement stmt = conn.createStatement()) {
617 stmt.execute(PRAGMA_SYNC_OFF);
618 stmt.execute(PRAGMA_READ_UNCOMMITTED_TRUE);
619 stmt.execute(PRAGMA_ENCODING_UTF8);
620 stmt.execute(PRAGMA_PAGE_SIZE_4096);
621 stmt.execute(PRAGMA_FOREIGN_KEYS_ON);
622 }
catch (SQLException ex) {
623 throw new TskCoreException(
"Error setting pragmas", ex);
628 void performPostTableInitialization(Connection conn)
throws TskCoreException {