Unified the SQL for schema creation.

This commit is contained in:
Raman Arora 2020-02-11 10:54:31 -05:00
parent 3877804a7c
commit ed1443aa68
3 changed files with 416 additions and 472 deletions

View File

@ -3418,7 +3418,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
case POSTGRESQL: case POSTGRESQL:
addAttributeSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause(); //NON-NLS addAttributeSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause(); //NON-NLS
// RAMAN TBD: get these from RdbmsCentralRepoSchemaFactory
addSsidTableTemplate = RdbmsCentralRepoSchemaFactory.getCreateArtifactInstancesTableTemplate(CentralRepoPlatforms.POSTGRESQL); addSsidTableTemplate = RdbmsCentralRepoSchemaFactory.getCreateArtifactInstancesTableTemplate(CentralRepoPlatforms.POSTGRESQL);
addCaseIdIndexTemplate = RdbmsCentralRepoSchemaFactory.getAddCaseIdIndexTemplate(); addCaseIdIndexTemplate = RdbmsCentralRepoSchemaFactory.getAddCaseIdIndexTemplate();
addDataSourceIdIndexTemplate = RdbmsCentralRepoSchemaFactory.getAddDataSourceIdIndexTemplate(); addDataSourceIdIndexTemplate = RdbmsCentralRepoSchemaFactory.getAddDataSourceIdIndexTemplate();

View File

@ -1,7 +1,20 @@
/* /*
* To change this license header, choose License Headers in Project Properties. * Central Repository
* To change this template file, choose Tools | Templates *
* and open the template in the editor. * Copyright 2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.sleuthkit.autopsy.centralrepository.datamodel; package org.sleuthkit.autopsy.centralrepository.datamodel;
@ -12,7 +25,6 @@ import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import static org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepo.SOFTWARE_CR_DB_SCHEMA_VERSION; import static org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepo.SOFTWARE_CR_DB_SCHEMA_VERSION;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
//import static org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings.getCreateArtifactInstancesTableTemplate;
/** /**
* Creates the CR schema and populates it with initial data. * Creates the CR schema and populates it with initial data.
@ -36,26 +48,10 @@ public class RdbmsCentralRepoSchemaFactory {
private final static String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096"; private final static String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096";
private final static String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON"; private final static String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON";
/**
* Returns instance of singleton.
*
* @throws CentralRepoException
*/
// public static RdbmsCentralRepoSchemaFactory getInstance() throws CentralRepoException {
//
// if (instance == null) {
// instance = new RdbmsCentralRepoSchemaFactory();
// }
//
// return instance;
// }
public RdbmsCentralRepoSchemaFactory(CentralRepoPlatforms selectedPlatform) throws CentralRepoException {
//CentralRepoPlatforms selectedPlatform = CentralRepoPlatforms.DISABLED;
//if (CentralRepoDbUtil.allowUseOfCentralRepository()) {
// selectedPlatform = CentralRepoPlatforms.getSelectedPlatform();
//}
public RdbmsCentralRepoSchemaFactory(CentralRepoPlatforms selectedPlatform) throws CentralRepoException {
this.selectedPlatform = selectedPlatform; this.selectedPlatform = selectedPlatform;
switch (selectedPlatform) { switch (selectedPlatform) {
case POSTGRESQL: case POSTGRESQL:
rdbmsCentralRepo = PostgresCentralRepo.getInstance(); rdbmsCentralRepo = PostgresCentralRepo.getInstance();
@ -68,427 +64,382 @@ public class RdbmsCentralRepoSchemaFactory {
} }
} }
/**
* Initialize the database schema.
*
* Requires valid connectionPool.
*
* This method is called from within connect(), so we cannot call connect()
* to get a connection. This method is called after setupConnectionPool(),
* so it is safe to assume that a valid connectionPool exists. The
* implementation of connect() is synchronized, so we can safely use the
* connectionPool object directly.
*/
public boolean initializeDatabaseSchema() { public boolean initializeDatabaseSchema() {
// The "id" column is an alias for the built-in 64-bit int "rowid" column.
// RA TEMP - call the method from platform specific inner class. // It is autoincrementing by default and must be of type "integer primary key".
// Eventually those two methods need to get unified here // We've omitted the autoincrement argument because we are not currently
// using the id value to search for specific rows, so we do not care
switch (selectedPlatform) { // if a rowid is re-used after an existing rows was previously deleted.
case POSTGRESQL: StringBuilder createOrganizationsTable = new StringBuilder();
// RAMAN TBD createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
return PostgresCRSchemaCreator.initializeDatabaseSchema(rdbmsCentralRepo, selectedPlatform);
//break; createOrganizationsTable.append(getNumericPrimaryKeyClause("id", selectedPlatform));
case SQLITE: createOrganizationsTable.append("org_name text NOT NULL,");
return SQLiteCRSchemaCreator.initializeDatabaseSchema(rdbmsCentralRepo, selectedPlatform); createOrganizationsTable.append("poc_name text NOT NULL,");
//break; createOrganizationsTable.append("poc_email text NOT NULL,");
default: createOrganizationsTable.append("poc_phone text NOT NULL,");
createOrganizationsTable.append("CONSTRAINT org_name_unique UNIQUE (org_name)");
createOrganizationsTable.append(")");
// NOTE: The organizations will only have a small number of rows, so
// an index is probably not worthwhile.
StringBuilder createCasesTable = new StringBuilder();
createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
createCasesTable.append(getNumericPrimaryKeyClause("id", selectedPlatform));
createCasesTable.append("case_uid text NOT NULL,");
createCasesTable.append("org_id integer,");
createCasesTable.append("case_name text NOT NULL,");
createCasesTable.append("creation_date text NOT NULL,");
createCasesTable.append("case_number text,");
createCasesTable.append("examiner_name text,");
createCasesTable.append("examiner_email text,");
createCasesTable.append("examiner_phone text,");
createCasesTable.append("notes text,");
createCasesTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,");
createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE(case_uid)").append(getOnConflictIgnoreClause(selectedPlatform));
createCasesTable.append(")");
// NOTE: when there are few cases in the cases table, these indices may not be worthwhile
String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
StringBuilder createReferenceSetsTable = new StringBuilder();
createReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS reference_sets (");
createReferenceSetsTable.append(getNumericPrimaryKeyClause("id", selectedPlatform));
createReferenceSetsTable.append("org_id integer NOT NULL,");
createReferenceSetsTable.append("set_name text NOT NULL,");
createReferenceSetsTable.append("version text NOT NULL,");
createReferenceSetsTable.append("known_status integer NOT NULL,");
createReferenceSetsTable.append("read_only boolean NOT NULL,");
createReferenceSetsTable.append("type integer NOT NULL,");
createReferenceSetsTable.append("import_date text NOT NULL,");
createReferenceSetsTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,");
createReferenceSetsTable.append("CONSTRAINT hash_set_unique UNIQUE (set_name, version)");
createReferenceSetsTable.append(")");
String referenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS reference_sets_org_id ON reference_sets (org_id)";
// Each "%s" will be replaced with the relevant reference_TYPE table name.
StringBuilder createReferenceTypesTableTemplate = new StringBuilder();
createReferenceTypesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s (");
createReferenceTypesTableTemplate.append(getNumericPrimaryKeyClause("id", selectedPlatform));
createReferenceTypesTableTemplate.append("reference_set_id integer,");
createReferenceTypesTableTemplate.append("value text NOT NULL,");
createReferenceTypesTableTemplate.append("known_status integer NOT NULL,");
createReferenceTypesTableTemplate.append("comment text,");
createReferenceTypesTableTemplate.append("CONSTRAINT %s_multi_unique UNIQUE(reference_set_id, value)").append(getOnConflictIgnoreClause(selectedPlatform)).append(",");
createReferenceTypesTableTemplate.append("foreign key (reference_set_id) references reference_sets(id) ON UPDATE SET NULL ON DELETE SET NULL");
createReferenceTypesTableTemplate.append(")");
// Each "%s" will be replaced with the relevant reference_TYPE table name.
String referenceTypesIdx1 = "CREATE INDEX IF NOT EXISTS %s_value ON %s (value)";
String referenceTypesIdx2 = "CREATE INDEX IF NOT EXISTS %s_value_known_status ON %s (value, known_status)";
StringBuilder createCorrelationTypesTable = new StringBuilder();
createCorrelationTypesTable.append("CREATE TABLE IF NOT EXISTS correlation_types (");
createCorrelationTypesTable.append(getNumericPrimaryKeyClause("id", selectedPlatform));
createCorrelationTypesTable.append("display_name text NOT NULL,");
createCorrelationTypesTable.append("db_table_name text NOT NULL,");
createCorrelationTypesTable.append("supported integer NOT NULL,");
createCorrelationTypesTable.append("enabled integer NOT NULL,");
createCorrelationTypesTable.append("CONSTRAINT correlation_types_names UNIQUE (display_name, db_table_name)");
createCorrelationTypesTable.append(")");
String createArtifactInstancesTableTemplate = getCreateArtifactInstancesTableTemplate(selectedPlatform);
String instancesCaseIdIdx = getAddCaseIdIndexTemplate();
String instancesDatasourceIdIdx = getAddDataSourceIdIndexTemplate();
String instancesValueIdx = getAddValueIndexTemplate();
String instancesKnownStatusIdx = getAddKnownStatusIndexTemplate();
String instancesObjectIdIdx = getAddObjectIdIndexTemplate();
// NOTE: the db_info table currenly only has 1 row, so having an index
// provides no benefit.
Connection conn = null;
try {
conn = rdbmsCentralRepo.getEphemeralConnection();
if (null == conn) {
return false; return false;
} }
} Statement stmt = conn.createStatement();
// TBD RAMAN - temporary container to store all SQLite methods, till we unify... // these setting PRAGMAs are SQLIte spcific
public static class SQLiteCRSchemaCreator { if (selectedPlatform == CentralRepoPlatforms.SQLITE) {
/**
* Initialize the database schema.
*
* Requires valid connectionPool.
*
* This method is called from within connect(), so we cannot call
* connect() to get a connection. This method is called after
* setupConnectionPool(), so it is safe to assume that a valid
* connectionPool exists. The implementation of connect() is
* synchronized, so we can safely use the connectionPool object
* directly.
*/
public static boolean initializeDatabaseSchema(RdbmsCentralRepo rdbmsCentralRepo, CentralRepoPlatforms selectedPlatform ) {
// The "id" column is an alias for the built-in 64-bit int "rowid" column.
// It is autoincrementing by default and must be of type "integer primary key".
// We've omitted the autoincrement argument because we are not currently
// using the id value to search for specific rows, so we do not care
// if a rowid is re-used after an existing rows was previously deleted.
StringBuilder createOrganizationsTable = new StringBuilder();
createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
createOrganizationsTable.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
//createOrganizationsTable.append("id integer primary key autoincrement NOT NULL,");
createOrganizationsTable.append("org_name text NOT NULL,");
createOrganizationsTable.append("poc_name text NOT NULL,");
createOrganizationsTable.append("poc_email text NOT NULL,");
createOrganizationsTable.append("poc_phone text NOT NULL,");
createOrganizationsTable.append("CONSTRAINT org_name_unique UNIQUE (org_name)");
createOrganizationsTable.append(")");
// NOTE: The organizations will only have a small number of rows, so
// an index is probably not worthwhile.
StringBuilder createCasesTable = new StringBuilder();
createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
createCasesTable.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
//createCasesTable.append("id integer primary key autoincrement NOT NULL,");
createCasesTable.append("case_uid text NOT NULL,");
createCasesTable.append("org_id integer,");
createCasesTable.append("case_name text NOT NULL,");
createCasesTable.append("creation_date text NOT NULL,");
createCasesTable.append("case_number text,");
createCasesTable.append("examiner_name text,");
createCasesTable.append("examiner_email text,");
createCasesTable.append("examiner_phone text,");
createCasesTable.append("notes text,");
createCasesTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,");
createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE(case_uid)" ).append(getOnConflictIgnoreClause(selectedPlatform));
createCasesTable.append(")");
// NOTE: when there are few cases in the cases table, these indices may not be worthwhile
String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
StringBuilder createReferenceSetsTable = new StringBuilder();
createReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS reference_sets (");
createReferenceSetsTable.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
//createReferenceSetsTable.append("id integer primary key autoincrement NOT NULL,");
createReferenceSetsTable.append("org_id integer NOT NULL,");
createReferenceSetsTable.append("set_name text NOT NULL,");
createReferenceSetsTable.append("version text NOT NULL,");
createReferenceSetsTable.append("known_status integer NOT NULL,");
createReferenceSetsTable.append("read_only boolean NOT NULL,");
createReferenceSetsTable.append("type integer NOT NULL,");
createReferenceSetsTable.append("import_date text NOT NULL,");
createReferenceSetsTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,");
createReferenceSetsTable.append("CONSTRAINT hash_set_unique UNIQUE (set_name, version)");
createReferenceSetsTable.append(")");
String referenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS reference_sets_org_id ON reference_sets (org_id)";
// Each "%s" will be replaced with the relevant reference_TYPE table name.
StringBuilder createReferenceTypesTableTemplate = new StringBuilder();
createReferenceTypesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s (");
createReferenceTypesTableTemplate.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
//createReferenceTypesTableTemplate.append("id integer primary key autoincrement NOT NULL,");
createReferenceTypesTableTemplate.append("reference_set_id integer,");
createReferenceTypesTableTemplate.append("value text NOT NULL,");
createReferenceTypesTableTemplate.append("known_status integer NOT NULL,");
createReferenceTypesTableTemplate.append("comment text,");
createReferenceTypesTableTemplate.append("CONSTRAINT %s_multi_unique UNIQUE(reference_set_id, value)").append(getOnConflictIgnoreClause(selectedPlatform)).append(",");
createReferenceTypesTableTemplate.append("foreign key (reference_set_id) references reference_sets(id) ON UPDATE SET NULL ON DELETE SET NULL");
createReferenceTypesTableTemplate.append(")");
// Each "%s" will be replaced with the relevant reference_TYPE table name.
String referenceTypesIdx1 = "CREATE INDEX IF NOT EXISTS %s_value ON %s (value)";
String referenceTypesIdx2 = "CREATE INDEX IF NOT EXISTS %s_value_known_status ON %s (value, known_status)";
StringBuilder createCorrelationTypesTable = new StringBuilder();
createCorrelationTypesTable.append("CREATE TABLE IF NOT EXISTS correlation_types (");
createCorrelationTypesTable.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
//createCorrelationTypesTable.append("id integer primary key autoincrement NOT NULL,");
createCorrelationTypesTable.append("display_name text NOT NULL,");
createCorrelationTypesTable.append("db_table_name text NOT NULL,");
createCorrelationTypesTable.append("supported integer NOT NULL,");
createCorrelationTypesTable.append("enabled integer NOT NULL,");
createCorrelationTypesTable.append("CONSTRAINT correlation_types_names UNIQUE (display_name, db_table_name)");
createCorrelationTypesTable.append(")");
String createArtifactInstancesTableTemplate = getCreateArtifactInstancesTableTemplate(selectedPlatform);
String instancesCaseIdIdx = getAddCaseIdIndexTemplate();
String instancesDatasourceIdIdx = getAddDataSourceIdIndexTemplate();
String instancesValueIdx = getAddValueIndexTemplate();
String instancesKnownStatusIdx = getAddKnownStatusIndexTemplate();
String instancesObjectIdIdx = getAddObjectIdIndexTemplate();
// NOTE: the db_info table currenly only has 1 row, so having an index
// provides no benefit.
Connection conn = null;
try {
conn = rdbmsCentralRepo.getEphemeralConnection();
if (null == conn) {
return false;
}
Statement stmt = conn.createStatement();
// RA TBD: this PRAGMA code is SQLIte spcific
stmt.execute(PRAGMA_JOURNAL_WAL); stmt.execute(PRAGMA_JOURNAL_WAL);
stmt.execute(PRAGMA_SYNC_OFF); stmt.execute(PRAGMA_SYNC_OFF);
stmt.execute(PRAGMA_READ_UNCOMMITTED_TRUE); stmt.execute(PRAGMA_READ_UNCOMMITTED_TRUE);
stmt.execute(PRAGMA_ENCODING_UTF8); stmt.execute(PRAGMA_ENCODING_UTF8);
stmt.execute(PRAGMA_PAGE_SIZE_4096); stmt.execute(PRAGMA_PAGE_SIZE_4096);
stmt.execute(PRAGMA_FOREIGN_KEYS_ON); stmt.execute(PRAGMA_FOREIGN_KEYS_ON);
}
stmt.execute(createOrganizationsTable.toString()); stmt.execute(createOrganizationsTable.toString());
stmt.execute(createCasesTable.toString()); stmt.execute(createCasesTable.toString());
stmt.execute(casesIdx1); stmt.execute(casesIdx1);
stmt.execute(casesIdx2); stmt.execute(casesIdx2);
stmt.execute(getCreateDataSourcesTableStatement(selectedPlatform)); stmt.execute(getCreateDataSourcesTableStatement(selectedPlatform));
stmt.execute(getAddDataSourcesNameIndexStatement()); stmt.execute(getAddDataSourcesNameIndexStatement());
stmt.execute(getAddDataSourcesObjectIdIndexStatement()); stmt.execute(getAddDataSourcesObjectIdIndexStatement());
stmt.execute(createReferenceSetsTable.toString()); stmt.execute(createReferenceSetsTable.toString());
stmt.execute(referenceSetsIdx1); stmt.execute(referenceSetsIdx1);
stmt.execute(createCorrelationTypesTable.toString()); stmt.execute(createCorrelationTypesTable.toString());
/* /*
* Note that the essentially useless id column in the following * Note that the essentially useless id column in the following
* table is required for backwards compatibility. Otherwise, the * table is required for backwards compatibility. Otherwise, the
* name column could be the primary key. * name column could be the primary key.
*/ */
StringBuilder dbInfoTable = new StringBuilder(); StringBuilder dbInfoTable = new StringBuilder();
dbInfoTable.append("CREATE TABLE db_info ("); dbInfoTable.append("CREATE TABLE db_info (");
dbInfoTable.append(getNumericPrimaryKeyClause("id", selectedPlatform)); dbInfoTable.append(getNumericPrimaryKeyClause("id", selectedPlatform));
dbInfoTable.append("name TEXT UNIQUE NOT NULL,"); dbInfoTable.append("name TEXT UNIQUE NOT NULL,");
dbInfoTable.append("value TEXT NOT NULL )"); dbInfoTable.append("value TEXT NOT NULL )");
stmt.execute(dbInfoTable.toString()); stmt.execute(dbInfoTable.toString());
stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() + "')"); stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() + "')");
stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMinor() + "')"); stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMinor() + "')");
stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() + "')"); stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() + "')");
stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMinor() + "')"); stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMinor() + "')");
// Create a separate instance and reference table for each artifact type // Create a separate instance and reference table for each artifact type
List<CorrelationAttributeInstance.Type> DEFAULT_CORRELATION_TYPES = CorrelationAttributeInstance.getDefaultCorrelationTypes(); List<CorrelationAttributeInstance.Type> DEFAULT_CORRELATION_TYPES = CorrelationAttributeInstance.getDefaultCorrelationTypes();
String reference_type_dbname; String reference_type_dbname;
String instance_type_dbname; String instance_type_dbname;
for (CorrelationAttributeInstance.Type type : DEFAULT_CORRELATION_TYPES) { for (CorrelationAttributeInstance.Type type : DEFAULT_CORRELATION_TYPES) {
reference_type_dbname = CentralRepoDbUtil.correlationTypeToReferenceTableName(type); reference_type_dbname = CentralRepoDbUtil.correlationTypeToReferenceTableName(type);
instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type); instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
stmt.execute(String.format(createArtifactInstancesTableTemplate, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(createArtifactInstancesTableTemplate, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesCaseIdIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesCaseIdIdx, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesDatasourceIdIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesDatasourceIdIdx, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesValueIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesValueIdx, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesKnownStatusIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesKnownStatusIdx, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesObjectIdIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesObjectIdIdx, instance_type_dbname, instance_type_dbname));
// FUTURE: allow more than the FILES type // FUTURE: allow more than the FILES type
if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) { if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
stmt.execute(String.format(createReferenceTypesTableTemplate.toString(), reference_type_dbname, reference_type_dbname)); stmt.execute(String.format(createReferenceTypesTableTemplate.toString(), reference_type_dbname, reference_type_dbname));
stmt.execute(String.format(referenceTypesIdx1, reference_type_dbname, reference_type_dbname)); stmt.execute(String.format(referenceTypesIdx1, reference_type_dbname, reference_type_dbname));
stmt.execute(String.format(referenceTypesIdx2, reference_type_dbname, reference_type_dbname)); stmt.execute(String.format(referenceTypesIdx2, reference_type_dbname, reference_type_dbname));
}
} }
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS
return false;
} catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, "Error getting default correlation types. Likely due to one or more Type's with an invalid db table name."); // NON-NLS
return false;
} finally {
CentralRepoDbUtil.closeConnection(conn);
} }
return true; } catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS
return false;
} catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, "Error getting default correlation types. Likely due to one or more Type's with an invalid db table name."); // NON-NLS
return false;
} finally {
CentralRepoDbUtil.closeConnection(conn);
} }
return true;
} }
// TBD RAMAN - temporary container to store all Pstgres methods, till we unify... // TBD RAMAN - temporary container to store all Pstgres methods, till we unify...
public static class PostgresCRSchemaCreator { // public static class PostgresCRSchemaCreator {
//
/** // /**
* Initialize the database schema. // * Initialize the database schema.
* // *
* Requires valid connectionPool. // * Requires valid connectionPool.
* // *
* This method is called from within connect(), so we cannot call // * This method is called from within connect(), so we cannot call
* connect() to get a connection. This method is called after // * connect() to get a connection. This method is called after
* setupConnectionPool(), so it is safe to assume that a valid // * setupConnectionPool(), so it is safe to assume that a valid
* connectionPool exists. The implementation of connect() is // * connectionPool exists. The implementation of connect() is
* synchronized, so we can safely use the connectionPool object // * synchronized, so we can safely use the connectionPool object
* directly. // * directly.
*/ // */
public static boolean initializeDatabaseSchema(RdbmsCentralRepo rdbmsCentralRepo, CentralRepoPlatforms selectedPlatform) { // public static boolean initializeDatabaseSchema(RdbmsCentralRepo rdbmsCentralRepo, CentralRepoPlatforms selectedPlatform) {
// The "id" column is an alias for the built-in 64-bit int "rowid" column. // // The "id" column is an alias for the built-in 64-bit int "rowid" column.
// It is autoincrementing by default and must be of type "integer primary key". // // It is autoincrementing by default and must be of type "integer primary key".
// We've omitted the autoincrement argument because we are not currently // // We've omitted the autoincrement argument because we are not currently
// using the id value to search for specific rows, so we do not care // // using the id value to search for specific rows, so we do not care
// if a rowid is re-used after an existing rows was previously deleted. // // if a rowid is re-used after an existing rows was previously deleted.
StringBuilder createOrganizationsTable = new StringBuilder(); // StringBuilder createOrganizationsTable = new StringBuilder();
createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations ("); // createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
//createOrganizationsTable.append("id SERIAL PRIMARY KEY,"); // //createOrganizationsTable.append("id SERIAL PRIMARY KEY,");
createOrganizationsTable.append(getNumericPrimaryKeyClause("id", selectedPlatform )); // createOrganizationsTable.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
createOrganizationsTable.append("org_name text NOT NULL,"); // createOrganizationsTable.append("org_name text NOT NULL,");
createOrganizationsTable.append("poc_name text NOT NULL,"); // createOrganizationsTable.append("poc_name text NOT NULL,");
createOrganizationsTable.append("poc_email text NOT NULL,"); // createOrganizationsTable.append("poc_email text NOT NULL,");
createOrganizationsTable.append("poc_phone text NOT NULL,"); // createOrganizationsTable.append("poc_phone text NOT NULL,");
createOrganizationsTable.append("CONSTRAINT org_name_unique UNIQUE (org_name)"); // createOrganizationsTable.append("CONSTRAINT org_name_unique UNIQUE (org_name)");
createOrganizationsTable.append(")"); // createOrganizationsTable.append(")");
//
// NOTE: The organizations will only have a small number of rows, so // // NOTE: The organizations will only have a small number of rows, so
// an index is probably not worthwhile. // // an index is probably not worthwhile.
StringBuilder createCasesTable = new StringBuilder(); // StringBuilder createCasesTable = new StringBuilder();
createCasesTable.append("CREATE TABLE IF NOT EXISTS cases ("); // createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
createCasesTable.append(getNumericPrimaryKeyClause("id", selectedPlatform )); // createCasesTable.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
//createCasesTable.append("id SERIAL PRIMARY KEY,"); // //createCasesTable.append("id SERIAL PRIMARY KEY,");
createCasesTable.append("case_uid text NOT NULL,"); // createCasesTable.append("case_uid text NOT NULL,");
createCasesTable.append("org_id integer,"); // createCasesTable.append("org_id integer,");
createCasesTable.append("case_name text NOT NULL,"); // createCasesTable.append("case_name text NOT NULL,");
createCasesTable.append("creation_date text NOT NULL,"); // createCasesTable.append("creation_date text NOT NULL,");
createCasesTable.append("case_number text,"); // createCasesTable.append("case_number text,");
createCasesTable.append("examiner_name text,"); // createCasesTable.append("examiner_name text,");
createCasesTable.append("examiner_email text,"); // createCasesTable.append("examiner_email text,");
createCasesTable.append("examiner_phone text,"); // createCasesTable.append("examiner_phone text,");
createCasesTable.append("notes text,"); // createCasesTable.append("notes text,");
createCasesTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,"); // createCasesTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,");
//createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE (case_uid)"); // //createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE (case_uid)");
createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE (case_uid)" ).append(getOnConflictIgnoreClause(selectedPlatform)); // createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE (case_uid)" ).append(getOnConflictIgnoreClause(selectedPlatform));
createCasesTable.append(")"); // createCasesTable.append(")");
//
// NOTE: when there are few cases in the cases table, these indices may not be worthwhile // // NOTE: when there are few cases in the cases table, these indices may not be worthwhile
String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)"; // String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)"; // String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
//
StringBuilder createReferenceSetsTable = new StringBuilder(); // StringBuilder createReferenceSetsTable = new StringBuilder();
createReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS reference_sets ("); // createReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS reference_sets (");
createReferenceSetsTable.append(getNumericPrimaryKeyClause("id", selectedPlatform )); // createReferenceSetsTable.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
//createReferenceSetsTable.append("id SERIAL PRIMARY KEY,"); // //createReferenceSetsTable.append("id SERIAL PRIMARY KEY,");
createReferenceSetsTable.append("org_id integer NOT NULL,"); // createReferenceSetsTable.append("org_id integer NOT NULL,");
createReferenceSetsTable.append("set_name text NOT NULL,"); // createReferenceSetsTable.append("set_name text NOT NULL,");
createReferenceSetsTable.append("version text NOT NULL,"); // createReferenceSetsTable.append("version text NOT NULL,");
createReferenceSetsTable.append("known_status integer NOT NULL,"); // createReferenceSetsTable.append("known_status integer NOT NULL,");
createReferenceSetsTable.append("read_only boolean NOT NULL,"); // createReferenceSetsTable.append("read_only boolean NOT NULL,");
createReferenceSetsTable.append("type integer NOT NULL,"); // createReferenceSetsTable.append("type integer NOT NULL,");
createReferenceSetsTable.append("import_date text NOT NULL,"); // createReferenceSetsTable.append("import_date text NOT NULL,");
createReferenceSetsTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,"); // createReferenceSetsTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,");
createReferenceSetsTable.append("CONSTRAINT hash_set_unique UNIQUE (set_name, version)"); // createReferenceSetsTable.append("CONSTRAINT hash_set_unique UNIQUE (set_name, version)");
createReferenceSetsTable.append(")"); // createReferenceSetsTable.append(")");
//
String referenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS reference_sets_org_id ON reference_sets (org_id)"; // String referenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS reference_sets_org_id ON reference_sets (org_id)";
//
// Each "%s" will be replaced with the relevant reference_TYPE table name. // // Each "%s" will be replaced with the relevant reference_TYPE table name.
StringBuilder createReferenceTypesTableTemplate = new StringBuilder(); // StringBuilder createReferenceTypesTableTemplate = new StringBuilder();
createReferenceTypesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s ("); // createReferenceTypesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s (");
createReferenceTypesTableTemplate.append(getNumericPrimaryKeyClause("id", selectedPlatform )); // createReferenceTypesTableTemplate.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
createReferenceTypesTableTemplate.append("reference_set_id integer,"); // createReferenceTypesTableTemplate.append("reference_set_id integer,");
createReferenceTypesTableTemplate.append("value text NOT NULL,"); // createReferenceTypesTableTemplate.append("value text NOT NULL,");
createReferenceTypesTableTemplate.append("known_status integer NOT NULL,"); // createReferenceTypesTableTemplate.append("known_status integer NOT NULL,");
createReferenceTypesTableTemplate.append("comment text,"); // createReferenceTypesTableTemplate.append("comment text,");
createReferenceTypesTableTemplate.append("CONSTRAINT %s_multi_unique UNIQUE(reference_set_id, value)").append(getOnConflictIgnoreClause(selectedPlatform)).append(","); // createReferenceTypesTableTemplate.append("CONSTRAINT %s_multi_unique UNIQUE(reference_set_id, value)").append(getOnConflictIgnoreClause(selectedPlatform)).append(",");
createReferenceTypesTableTemplate.append("foreign key (reference_set_id) references reference_sets(id) ON UPDATE SET NULL ON DELETE SET NULL"); // createReferenceTypesTableTemplate.append("foreign key (reference_set_id) references reference_sets(id) ON UPDATE SET NULL ON DELETE SET NULL");
createReferenceTypesTableTemplate.append(")"); // createReferenceTypesTableTemplate.append(")");
//
// Each "%s" will be replaced with the relevant reference_TYPE table name. // // Each "%s" will be replaced with the relevant reference_TYPE table name.
String referenceTypesIdx1 = "CREATE INDEX IF NOT EXISTS %s_value ON %s (value)"; // String referenceTypesIdx1 = "CREATE INDEX IF NOT EXISTS %s_value ON %s (value)";
String referenceTypesIdx2 = "CREATE INDEX IF NOT EXISTS %s_value_known_status ON %s (value, known_status)"; // String referenceTypesIdx2 = "CREATE INDEX IF NOT EXISTS %s_value_known_status ON %s (value, known_status)";
//
StringBuilder createCorrelationTypesTable = new StringBuilder(); // StringBuilder createCorrelationTypesTable = new StringBuilder();
createCorrelationTypesTable.append("CREATE TABLE IF NOT EXISTS correlation_types ("); // createCorrelationTypesTable.append("CREATE TABLE IF NOT EXISTS correlation_types (");
createCorrelationTypesTable.append(getNumericPrimaryKeyClause("id", selectedPlatform )); // createCorrelationTypesTable.append(getNumericPrimaryKeyClause("id", selectedPlatform ));
createCorrelationTypesTable.append("display_name text NOT NULL,"); // createCorrelationTypesTable.append("display_name text NOT NULL,");
createCorrelationTypesTable.append("db_table_name text NOT NULL,"); // createCorrelationTypesTable.append("db_table_name text NOT NULL,");
createCorrelationTypesTable.append("supported integer NOT NULL,"); // createCorrelationTypesTable.append("supported integer NOT NULL,");
createCorrelationTypesTable.append("enabled integer NOT NULL,"); // createCorrelationTypesTable.append("enabled integer NOT NULL,");
createCorrelationTypesTable.append("CONSTRAINT correlation_types_names UNIQUE (display_name, db_table_name)"); // createCorrelationTypesTable.append("CONSTRAINT correlation_types_names UNIQUE (display_name, db_table_name)");
createCorrelationTypesTable.append(")"); // createCorrelationTypesTable.append(")");
//
String createArtifactInstancesTableTemplate = getCreateArtifactInstancesTableTemplate(selectedPlatform); // String createArtifactInstancesTableTemplate = getCreateArtifactInstancesTableTemplate(selectedPlatform);
//
String instancesCaseIdIdx = getAddCaseIdIndexTemplate(); // String instancesCaseIdIdx = getAddCaseIdIndexTemplate();
String instancesDatasourceIdIdx = getAddDataSourceIdIndexTemplate(); // String instancesDatasourceIdIdx = getAddDataSourceIdIndexTemplate();
String instancesValueIdx = getAddValueIndexTemplate(); // String instancesValueIdx = getAddValueIndexTemplate();
String instancesKnownStatusIdx = getAddKnownStatusIndexTemplate(); // String instancesKnownStatusIdx = getAddKnownStatusIndexTemplate();
String instancesObjectIdIdx = getAddObjectIdIndexTemplate(); // String instancesObjectIdIdx = getAddObjectIdIndexTemplate();
//
// NOTE: the db_info table currenly only has 1 row, so having an index // // NOTE: the db_info table currenly only has 1 row, so having an index
// provides no benefit. // // provides no benefit.
Connection conn = null; // Connection conn = null;
try { // try {
conn = rdbmsCentralRepo.getEphemeralConnection(); // conn = rdbmsCentralRepo.getEphemeralConnection();
if (null == conn) { // if (null == conn) {
return false; // return false;
} // }
Statement stmt = conn.createStatement(); // Statement stmt = conn.createStatement();
//
stmt.execute(createOrganizationsTable.toString()); // stmt.execute(createOrganizationsTable.toString());
//
stmt.execute(createCasesTable.toString()); // stmt.execute(createCasesTable.toString());
stmt.execute(casesIdx1); // stmt.execute(casesIdx1);
stmt.execute(casesIdx2); // stmt.execute(casesIdx2);
//
stmt.execute(getCreateDataSourcesTableStatement(selectedPlatform)); // stmt.execute(getCreateDataSourcesTableStatement(selectedPlatform));
stmt.execute(getAddDataSourcesNameIndexStatement()); // stmt.execute(getAddDataSourcesNameIndexStatement());
stmt.execute(getAddDataSourcesObjectIdIndexStatement()); // stmt.execute(getAddDataSourcesObjectIdIndexStatement());
//
stmt.execute(createReferenceSetsTable.toString()); // stmt.execute(createReferenceSetsTable.toString());
stmt.execute(referenceSetsIdx1); // stmt.execute(referenceSetsIdx1);
//
stmt.execute(createCorrelationTypesTable.toString()); // stmt.execute(createCorrelationTypesTable.toString());
//
/* // /*
* Note that the essentially useless id column in the following // * Note that the essentially useless id column in the following
* table is required for backwards compatibility. Otherwise, the // * table is required for backwards compatibility. Otherwise, the
* name column could be the primary key. // * name column could be the primary key.
*/ // */
StringBuilder dbInfoTable = new StringBuilder(); // StringBuilder dbInfoTable = new StringBuilder();
dbInfoTable.append("CREATE TABLE db_info ("); // dbInfoTable.append("CREATE TABLE db_info (");
dbInfoTable.append(getNumericPrimaryKeyClause("id", selectedPlatform)); // dbInfoTable.append(getNumericPrimaryKeyClause("id", selectedPlatform));
dbInfoTable.append("name TEXT UNIQUE NOT NULL,"); // dbInfoTable.append("name TEXT UNIQUE NOT NULL,");
dbInfoTable.append("value TEXT NOT NULL )"); // dbInfoTable.append("value TEXT NOT NULL )");
//
stmt.execute(dbInfoTable.toString()); // stmt.execute(dbInfoTable.toString());
stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() + "')"); // stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() + "')");
stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMinor() + "')"); // stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMinor() + "')");
stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() + "')"); // stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() + "')");
stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMinor() + "')"); // stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMinor() + "')");
//
// Create a separate instance and reference table for each correlation type // // Create a separate instance and reference table for each correlation type
List<CorrelationAttributeInstance.Type> DEFAULT_CORRELATION_TYPES = CorrelationAttributeInstance.getDefaultCorrelationTypes(); // List<CorrelationAttributeInstance.Type> DEFAULT_CORRELATION_TYPES = CorrelationAttributeInstance.getDefaultCorrelationTypes();
//
String reference_type_dbname; // String reference_type_dbname;
String instance_type_dbname; // String instance_type_dbname;
for (CorrelationAttributeInstance.Type type : DEFAULT_CORRELATION_TYPES) { // for (CorrelationAttributeInstance.Type type : DEFAULT_CORRELATION_TYPES) {
reference_type_dbname = CentralRepoDbUtil.correlationTypeToReferenceTableName(type); // reference_type_dbname = CentralRepoDbUtil.correlationTypeToReferenceTableName(type);
instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type); // instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
//
stmt.execute(String.format(createArtifactInstancesTableTemplate, instance_type_dbname, instance_type_dbname)); // stmt.execute(String.format(createArtifactInstancesTableTemplate, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesCaseIdIdx, instance_type_dbname, instance_type_dbname)); // stmt.execute(String.format(instancesCaseIdIdx, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesDatasourceIdIdx, instance_type_dbname, instance_type_dbname)); // stmt.execute(String.format(instancesDatasourceIdIdx, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesValueIdx, instance_type_dbname, instance_type_dbname)); // stmt.execute(String.format(instancesValueIdx, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesKnownStatusIdx, instance_type_dbname, instance_type_dbname)); // stmt.execute(String.format(instancesKnownStatusIdx, instance_type_dbname, instance_type_dbname));
stmt.execute(String.format(instancesObjectIdIdx, instance_type_dbname, instance_type_dbname)); // stmt.execute(String.format(instancesObjectIdIdx, instance_type_dbname, instance_type_dbname));
//
// FUTURE: allow more than the FILES type // // FUTURE: allow more than the FILES type
if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) { // if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
stmt.execute(String.format(createReferenceTypesTableTemplate.toString(), reference_type_dbname, reference_type_dbname)); // stmt.execute(String.format(createReferenceTypesTableTemplate.toString(), reference_type_dbname, reference_type_dbname));
stmt.execute(String.format(referenceTypesIdx1, reference_type_dbname, reference_type_dbname)); // stmt.execute(String.format(referenceTypesIdx1, reference_type_dbname, reference_type_dbname));
stmt.execute(String.format(referenceTypesIdx2, reference_type_dbname, reference_type_dbname)); // stmt.execute(String.format(referenceTypesIdx2, reference_type_dbname, reference_type_dbname));
} // }
} // }
//
} catch (SQLException ex) { // } catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS // LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS
return false; // return false;
} catch (CentralRepoException ex) { // } catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, "Error getting default correlation types. Likely due to one or more Type's with an invalid db table name."); // NON-NLS // LOGGER.log(Level.SEVERE, "Error getting default correlation types. Likely due to one or more Type's with an invalid db table name."); // NON-NLS
return false; // return false;
} finally { // } finally {
CentralRepoDbUtil.closeConnection(conn); // CentralRepoDbUtil.closeConnection(conn);
} // }
return true; // return true;
} // }
//
//
//
} // }
public boolean insertDefaultDatabaseContent() { public boolean insertDefaultDatabaseContent() {
Connection conn = rdbmsCentralRepo.getEphemeralConnection(); Connection conn = rdbmsCentralRepo.getEphemeralConnection();
if (null == conn) { if (null == conn) {
@ -499,54 +450,52 @@ public class RdbmsCentralRepoSchemaFactory {
CentralRepoDbUtil.closeConnection(conn); CentralRepoDbUtil.closeConnection(conn);
return result; return result;
} }
/**
* Get the template String for creating a new _instances table in a Sqlite
* central repository. %s will exist in the template where the name of the
* new table will be added.
*
* @return a String which is a template for creating a new _instances table
*/
static String getCreateArtifactInstancesTableTemplate(CentralRepoPlatforms selectedPlatform) {
// Each "%s" will be replaced with the relevant TYPE_instances table name.
return "CREATE TABLE IF NOT EXISTS %s ("
+ getNumericPrimaryKeyClause("id", selectedPlatform)
+ "case_id integer NOT NULL,"
+ "data_source_id integer NOT NULL,"
+ "value text NOT NULL,"
+ "file_path text NOT NULL,"
+ "known_status integer NOT NULL,"
+ "comment text,"
+ "file_obj_id BIGINT,"
+ "CONSTRAINT %s_multi_unique UNIQUE(data_source_id, value, file_path)" + getOnConflictIgnoreClause(selectedPlatform) + ","
+ "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
+ "foreign key (data_source_id) references data_sources(id) ON UPDATE SET NULL ON DELETE SET NULL)";
}
/**
* Get the statement String for creating a new data_sources table in a
* Sqlite central repository.
*
* @return a String which is a statement for creating a new data_sources
* table
*/
static String getCreateDataSourcesTableStatement(CentralRepoPlatforms selectedPlatform) {
return "CREATE TABLE IF NOT EXISTS data_sources ("
+ getNumericPrimaryKeyClause("id", selectedPlatform)
+ "case_id integer NOT NULL,"
+ "device_id text NOT NULL,"
+ "name text NOT NULL,"
+ "datasource_obj_id integer," // RAMAN TBD: does integer suffice for PostGres. Old code used integer in some places but used BIGINT in other.
+ "md5 text DEFAULT NULL,"
+ "sha1 text DEFAULT NULL,"
+ "sha256 text DEFAULT NULL,"
+ "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
+ "CONSTRAINT datasource_unique UNIQUE (case_id, datasource_obj_id))";
}
/** /**
* Get the template String for creating a new _instances table in a
* Sqlite central repository. %s will exist in the template where the
* name of the new table will be addedd.
*
* @return a String which is a template for cretating a new _instances
* table
*/
static String getCreateArtifactInstancesTableTemplate(CentralRepoPlatforms selectedPlatform) {
// Each "%s" will be replaced with the relevant TYPE_instances table name.
return "CREATE TABLE IF NOT EXISTS %s ("
+ getNumericPrimaryKeyClause("id", selectedPlatform )
+ "case_id integer NOT NULL,"
+ "data_source_id integer NOT NULL,"
+ "value text NOT NULL,"
+ "file_path text NOT NULL,"
+ "known_status integer NOT NULL,"
+ "comment text,"
+ "file_obj_id BIGINT,"
+ "CONSTRAINT %s_multi_unique UNIQUE(data_source_id, value, file_path)" + getOnConflictIgnoreClause(selectedPlatform) + ","
+ "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
+ "foreign key (data_source_id) references data_sources(id) ON UPDATE SET NULL ON DELETE SET NULL)";
}
/**
* Get the statement String for creating a new data_sources table in a
* Sqlite central repository.
*
* @return a String which is a statement for creating a new
* data_sources table
*/
static String getCreateDataSourcesTableStatement(CentralRepoPlatforms selectedPlatform) {
return "CREATE TABLE IF NOT EXISTS data_sources ("
+ getNumericPrimaryKeyClause("id", selectedPlatform )
+ "case_id integer NOT NULL,"
+ "device_id text NOT NULL,"
+ "name text NOT NULL,"
+ "datasource_obj_id integer," // RAMAN TBD: does integer suffice for PostGres. Old code used integer in some places but used BIGINT in other.
+ "md5 text DEFAULT NULL,"
+ "sha1 text DEFAULT NULL,"
+ "sha256 text DEFAULT NULL,"
+ "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
+ "CONSTRAINT datasource_unique UNIQUE (case_id, datasource_obj_id))";
}
/**
* Get the template for creating an index on the case_id column of an * Get the template for creating an index on the case_id column of an
* instance table. %s will exist in the template where the name of the new * instance table. %s will exist in the template where the name of the new
* table will be added. * table will be added.
@ -558,7 +507,7 @@ public class RdbmsCentralRepoSchemaFactory {
// Each "%s" will be replaced with the relevant TYPE_instances table name. // Each "%s" will be replaced with the relevant TYPE_instances table name.
return "CREATE INDEX IF NOT EXISTS %s_case_id ON %s (case_id)"; return "CREATE INDEX IF NOT EXISTS %s_case_id ON %s (case_id)";
} }
/** /**
* Get the template for creating an index on the data_source_id column of an * Get the template for creating an index on the data_source_id column of an
* instance table. %s will exist in the template where the name of the new * instance table. %s will exist in the template where the name of the new
@ -572,7 +521,6 @@ public class RdbmsCentralRepoSchemaFactory {
return "CREATE INDEX IF NOT EXISTS %s_data_source_id ON %s (data_source_id)"; return "CREATE INDEX IF NOT EXISTS %s_data_source_id ON %s (data_source_id)";
} }
/** /**
* Get the template for creating an index on the value column of an instance * Get the template for creating an index on the value column of an instance
* table. %s will exist in the template where the name of the new table will * table. %s will exist in the template where the name of the new table will
@ -611,8 +559,8 @@ public class RdbmsCentralRepoSchemaFactory {
// Each "%s" will be replaced with the relevant TYPE_instances table name. // Each "%s" will be replaced with the relevant TYPE_instances table name.
return "CREATE INDEX IF NOT EXISTS %s_file_obj_id ON %s (file_obj_id)"; return "CREATE INDEX IF NOT EXISTS %s_file_obj_id ON %s (file_obj_id)";
} }
/** /**
* Get the statement for creating an index on the name column of the * Get the statement for creating an index on the name column of the
* data_sources table. * data_sources table.
* *
@ -633,7 +581,7 @@ public class RdbmsCentralRepoSchemaFactory {
static String getAddDataSourcesObjectIdIndexStatement() { static String getAddDataSourcesObjectIdIndexStatement() {
return "CREATE INDEX IF NOT EXISTS data_sources_object_id ON data_sources (datasource_obj_id)"; return "CREATE INDEX IF NOT EXISTS data_sources_object_id ON data_sources (datasource_obj_id)";
} }
/** /**
* Builds SQL clause for a numeric primary key. Produces correct SQL based * Builds SQL clause for a numeric primary key. Produces correct SQL based
* on the selected CR platform/RDMBS. * on the selected CR platform/RDMBS.
@ -642,7 +590,6 @@ public class RdbmsCentralRepoSchemaFactory {
* *
* @return SQL clause to be used in a Create table statement * @return SQL clause to be used in a Create table statement
*/ */
// RA TEMP: selectedPlatform is passed as argument, eventually this should be used from the class and this method should not be static
private static String getNumericPrimaryKeyClause(String pkName, CentralRepoPlatforms selectedPlatform) { private static String getNumericPrimaryKeyClause(String pkName, CentralRepoPlatforms selectedPlatform) {
switch (selectedPlatform) { switch (selectedPlatform) {
case POSTGRESQL: case POSTGRESQL:
@ -652,14 +599,13 @@ public class RdbmsCentralRepoSchemaFactory {
} }
return ""; return "";
} }
/** /**
* Returns ON CONFLICT IGNORE clause for the specified database platform. * Returns ON CONFLICT IGNORE clause for the specified database platform.
* *
* *
* @return SQL clause. * @return SQL clause.
*/ */
// RA TEMP: selectedPlatform is passed as argument, eventually this should be used from the class and this method should not be static
private static String getOnConflictIgnoreClause(CentralRepoPlatforms selectedPlatform) { private static String getOnConflictIgnoreClause(CentralRepoPlatforms selectedPlatform) {
switch (selectedPlatform) { switch (selectedPlatform) {
case POSTGRESQL: case POSTGRESQL:

View File

@ -113,7 +113,6 @@ final class SqliteCentralRepo extends RdbmsCentralRepo {
@Override @Override
public void reset() throws CentralRepoException { public void reset() throws CentralRepoException {
try { try {
// RAMAN TBD: this should be moved to RdbmsCentralRepoSchemaFactory ??
acquireExclusiveLock(); acquireExclusiveLock();
Connection conn = connect(); Connection conn = connect();