Autopsy  4.9.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
SqliteEamDbSettings.java
Go to the documentation of this file.
1 /*
2  * Central Repository
3  *
4  * Copyright 2015-2017 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.centralrepository.datamodel;
20 
21 import java.io.File;
22 import java.io.IOException;
23 import java.nio.file.Files;
24 import java.nio.file.InvalidPathException;
25 import java.sql.Connection;
26 import java.sql.DriverManager;
27 import java.sql.SQLException;
28 import java.sql.Statement;
29 import java.util.List;
30 import java.util.logging.Level;
31 import java.util.regex.Pattern;
32 import static org.sleuthkit.autopsy.centralrepository.datamodel.AbstractSqlEamDb.CURRENT_DB_SCHEMA_VERSION;
36 
43 public final class SqliteEamDbSettings {
44 
45  private final static Logger LOGGER = Logger.getLogger(SqliteEamDbSettings.class.getName());
46  private final String DEFAULT_DBNAME = "central_repository.db"; // NON-NLS
47  private final String DEFAULT_DBDIRECTORY = PlatformUtil.getUserDirectory() + File.separator + "central_repository"; // NON-NLS
48  private final String JDBC_DRIVER = "org.sqlite.JDBC"; // NON-NLS
49  private final String JDBC_BASE_URI = "jdbc:sqlite:"; // NON-NLS
50  private final String VALIDATION_QUERY = "SELECT count(*) from sqlite_master"; // NON-NLS
51  private static final String PRAGMA_SYNC_OFF = "PRAGMA synchronous = OFF";
52  private static final String PRAGMA_SYNC_NORMAL = "PRAGMA synchronous = NORMAL";
53  private static final String PRAGMA_JOURNAL_WAL = "PRAGMA journal_mode = WAL";
54  private static final String PRAGMA_READ_UNCOMMITTED_TRUE = "PRAGMA read_uncommitted = True";
55  private static final String PRAGMA_ENCODING_UTF8 = "PRAGMA encoding = 'UTF-8'";
56  private static final String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096";
57  private static final String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON";
58  private final String DB_NAMES_REGEX = "[a-z][a-z0-9_]*(\\.db)?";
59  private String dbName;
60  private String dbDirectory;
61  private int bulkThreshold;
62 
64  loadSettings();
65  }
66 
67  public void loadSettings() {
68  dbName = ModuleSettings.getConfigSetting("CentralRepository", "db.sqlite.dbName"); // NON-NLS
69  if (dbName == null || dbName.isEmpty()) {
70  dbName = DEFAULT_DBNAME;
71  }
72 
73  dbDirectory = ModuleSettings.getConfigSetting("CentralRepository", "db.sqlite.dbDirectory"); // NON-NLS
74  if (dbDirectory == null || dbDirectory.isEmpty()) {
75  dbDirectory = DEFAULT_DBDIRECTORY;
76  }
77 
78  try {
79  String bulkThresholdString = ModuleSettings.getConfigSetting("CentralRepository", "db.sqlite.bulkThreshold"); // NON-NLS
80  if (bulkThresholdString == null || bulkThresholdString.isEmpty()) {
81  this.bulkThreshold = AbstractSqlEamDb.DEFAULT_BULK_THRESHHOLD;
82  } else {
83  this.bulkThreshold = Integer.parseInt(bulkThresholdString);
84  if (getBulkThreshold() <= 0) {
85  this.bulkThreshold = AbstractSqlEamDb.DEFAULT_BULK_THRESHHOLD;
86  }
87  }
88  } catch (NumberFormatException ex) {
89  this.bulkThreshold = AbstractSqlEamDb.DEFAULT_BULK_THRESHHOLD;
90  }
91  }
92 
93  public void saveSettings() {
95 
96  ModuleSettings.setConfigSetting("CentralRepository", "db.sqlite.dbName", getDbName()); // NON-NLS
97  ModuleSettings.setConfigSetting("CentralRepository", "db.sqlite.dbDirectory", getDbDirectory()); // NON-NLS
98  ModuleSettings.setConfigSetting("CentralRepository", "db.sqlite.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS
99  }
100 
106  public boolean dbFileExists() {
107  File dbFile = new File(getFileNameWithPath());
108  if (!dbFile.exists()) {
109  return false;
110  }
111  // It's unlikely, but make sure the file isn't actually a directory
112  return (!dbFile.isDirectory());
113  }
114 
120  public boolean dbDirectoryExists() {
121  // Ensure dbDirectory is a valid directory
122  File dbDir = new File(getDbDirectory());
123 
124  if (!dbDir.exists()) {
125  return false;
126  } else if (!dbDir.isDirectory()) {
127  return false;
128  }
129 
130  return true;
131 
132  }
133 
139  public boolean createDbDirectory() {
140  if (!dbDirectoryExists()) {
141  try {
142  File dbDir = new File(getDbDirectory());
143  Files.createDirectories(dbDir.toPath());
144  LOGGER.log(Level.INFO, "sqlite directory did not exist, created it at {0}.", getDbDirectory()); // NON-NLS
145  } catch (IOException | InvalidPathException | SecurityException ex) {
146  LOGGER.log(Level.SEVERE, "Failed to create sqlite database directory.", ex); // NON-NLS
147  return false;
148  }
149  }
150 
151  return true;
152  }
153 
159  public boolean deleteDatabase() {
160  File dbFile = new File(this.getFileNameWithPath());
161  return dbFile.delete();
162  }
163 
169  String getConnectionURL() {
170  StringBuilder url = new StringBuilder();
171  url.append(getJDBCBaseURI());
172  url.append(getFileNameWithPath());
173 
174  return url.toString();
175  }
176 
185  private Connection getEphemeralConnection() {
186  if (!dbDirectoryExists()) {
187  return null;
188  }
189 
190  Connection conn;
191  try {
192  String url = getConnectionURL();
193  Class.forName(getDriver());
194  conn = DriverManager.getConnection(url);
195  } catch (ClassNotFoundException | SQLException ex) {
196  LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to sqlite.", ex); // NON-NLS
197  conn = null;
198  }
199  return conn;
200  }
201 
208  public boolean verifyConnection() {
209  Connection conn = getEphemeralConnection();
210  if (null == conn) {
211  return false;
212  }
213 
214  boolean result = EamDbUtil.executeValidationQuery(conn, VALIDATION_QUERY);
216  return result;
217  }
218 
225  public boolean verifyDatabaseSchema() {
226  Connection conn = getEphemeralConnection();
227  if (null == conn) {
228  return false;
229  }
230 
231  boolean result = EamDbUtil.schemaVersionIsSet(conn);
233  return result;
234  }
235 
247  public boolean initializeDatabaseSchema() {
248  // The "id" column is an alias for the built-in 64-bit int "rowid" column.
249  // It is autoincrementing by default and must be of type "integer primary key".
250  // We've omitted the autoincrement argument because we are not currently
251  // using the id value to search for specific rows, so we do not care
252  // if a rowid is re-used after an existing rows was previously deleted.
253  StringBuilder createOrganizationsTable = new StringBuilder();
254  createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
255  createOrganizationsTable.append("id integer primary key autoincrement NOT NULL,");
256  createOrganizationsTable.append("org_name text NOT NULL,");
257  createOrganizationsTable.append("poc_name text NOT NULL,");
258  createOrganizationsTable.append("poc_email text NOT NULL,");
259  createOrganizationsTable.append("poc_phone text NOT NULL,");
260  createOrganizationsTable.append("CONSTRAINT org_name_unique UNIQUE (org_name)");
261  createOrganizationsTable.append(")");
262 
263  // NOTE: The organizations will only have a small number of rows, so
264  // an index is probably not worthwhile.
265  StringBuilder createCasesTable = new StringBuilder();
266  createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
267  createCasesTable.append("id integer primary key autoincrement NOT NULL,");
268  createCasesTable.append("case_uid text NOT NULL,");
269  createCasesTable.append("org_id integer,");
270  createCasesTable.append("case_name text NOT NULL,");
271  createCasesTable.append("creation_date text NOT NULL,");
272  createCasesTable.append("case_number text,");
273  createCasesTable.append("examiner_name text,");
274  createCasesTable.append("examiner_email text,");
275  createCasesTable.append("examiner_phone text,");
276  createCasesTable.append("notes text,");
277  createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE(case_uid) ON CONFLICT IGNORE,");
278  createCasesTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL");
279  createCasesTable.append(")");
280 
281  // NOTE: when there are few cases in the cases table, these indices may not be worthwhile
282  String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
283  String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
284 
285  StringBuilder createDataSourcesTable = new StringBuilder();
286  createDataSourcesTable.append("CREATE TABLE IF NOT EXISTS data_sources (");
287  createDataSourcesTable.append("id integer primary key autoincrement NOT NULL,");
288  createDataSourcesTable.append("case_id integer NOT NULL,");
289  createDataSourcesTable.append("device_id text NOT NULL,");
290  createDataSourcesTable.append("name text NOT NULL,");
291  createDataSourcesTable.append("datasource_obj_id integer,");
292  createDataSourcesTable.append("md5 text DEFAULT NULL,");
293  createDataSourcesTable.append("sha1 text DEFAULT NULL,");
294  createDataSourcesTable.append("sha256 text DEFAULT NULL,");
295  createDataSourcesTable.append("foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,");
296  createDataSourcesTable.append("CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name)");
297  createDataSourcesTable.append(")");
298 
299  String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)";
300  String dataSourceIdx2 = "CREATE INDEX IF NOT EXISTS data_sources_object_id ON data_sources (datasource_obj_id)";
301 
302  StringBuilder createReferenceSetsTable = new StringBuilder();
303  createReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS reference_sets (");
304  createReferenceSetsTable.append("id integer primary key autoincrement NOT NULL,");
305  createReferenceSetsTable.append("org_id integer NOT NULL,");
306  createReferenceSetsTable.append("set_name text NOT NULL,");
307  createReferenceSetsTable.append("version text NOT NULL,");
308  createReferenceSetsTable.append("known_status integer NOT NULL,");
309  createReferenceSetsTable.append("read_only boolean NOT NULL,");
310  createReferenceSetsTable.append("type integer NOT NULL,");
311  createReferenceSetsTable.append("import_date text NOT NULL,");
312  createReferenceSetsTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,");
313  createReferenceSetsTable.append("CONSTRAINT hash_set_unique UNIQUE (set_name, version)");
314  createReferenceSetsTable.append(")");
315 
316  String referenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS reference_sets_org_id ON reference_sets (org_id)";
317 
318  // Each "%s" will be replaced with the relevant reference_TYPE table name.
319  StringBuilder createReferenceTypesTableTemplate = new StringBuilder();
320  createReferenceTypesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s (");
321  createReferenceTypesTableTemplate.append("id integer primary key autoincrement NOT NULL,");
322  createReferenceTypesTableTemplate.append("reference_set_id integer,");
323  createReferenceTypesTableTemplate.append("value text NOT NULL,");
324  createReferenceTypesTableTemplate.append("known_status integer NOT NULL,");
325  createReferenceTypesTableTemplate.append("comment text,");
326  createReferenceTypesTableTemplate.append("CONSTRAINT %s_multi_unique UNIQUE(reference_set_id, value) ON CONFLICT IGNORE,");
327  createReferenceTypesTableTemplate.append("foreign key (reference_set_id) references reference_sets(id) ON UPDATE SET NULL ON DELETE SET NULL");
328  createReferenceTypesTableTemplate.append(")");
329 
330  // Each "%s" will be replaced with the relevant reference_TYPE table name.
331  String referenceTypesIdx1 = "CREATE INDEX IF NOT EXISTS %s_value ON %s (value)";
332  String referenceTypesIdx2 = "CREATE INDEX IF NOT EXISTS %s_value_known_status ON %s (value, known_status)";
333 
334  StringBuilder createCorrelationTypesTable = new StringBuilder();
335  createCorrelationTypesTable.append("CREATE TABLE IF NOT EXISTS correlation_types (");
336  createCorrelationTypesTable.append("id integer primary key autoincrement NOT NULL,");
337  createCorrelationTypesTable.append("display_name text NOT NULL,");
338  createCorrelationTypesTable.append("db_table_name text NOT NULL,");
339  createCorrelationTypesTable.append("supported integer NOT NULL,");
340  createCorrelationTypesTable.append("enabled integer NOT NULL,");
341  createCorrelationTypesTable.append("CONSTRAINT correlation_types_names UNIQUE (display_name, db_table_name)");
342  createCorrelationTypesTable.append(")");
343 
344  String createArtifactInstancesTableTemplate = getCreateArtifactInstancesTableTemplate();
345 
346  String instancesCaseIdIdx = getAddCaseIdIndexTemplate();
347  String instancesDatasourceIdIdx = getAddDataSourceIdIndexTemplate();
348  String instancesValueIdx = getAddValueIndexTemplate();
349  String instancesKnownStatusIdx = getAddKnownStatusIndexTemplate();
350  String instancesObjectIdIdx = getAddObjectIdIndexTemplate();
351 
352  // NOTE: the db_info table currenly only has 1 row, so having an index
353  // provides no benefit.
354  Connection conn = null;
355  try {
356  conn = getEphemeralConnection();
357  if (null == conn) {
358  return false;
359  }
360  Statement stmt = conn.createStatement();
361  stmt.execute(PRAGMA_JOURNAL_WAL);
362  stmt.execute(PRAGMA_SYNC_OFF);
363  stmt.execute(PRAGMA_READ_UNCOMMITTED_TRUE);
364  stmt.execute(PRAGMA_ENCODING_UTF8);
365  stmt.execute(PRAGMA_PAGE_SIZE_4096);
366  stmt.execute(PRAGMA_FOREIGN_KEYS_ON);
367 
368  stmt.execute(createOrganizationsTable.toString());
369 
370  stmt.execute(createCasesTable.toString());
371  stmt.execute(casesIdx1);
372  stmt.execute(casesIdx2);
373 
374  stmt.execute(createDataSourcesTable.toString());
375  stmt.execute(dataSourceIdx1);
376  stmt.execute(dataSourceIdx2);
377 
378  stmt.execute(createReferenceSetsTable.toString());
379  stmt.execute(referenceSetsIdx1);
380 
381  stmt.execute(createCorrelationTypesTable.toString());
382 
383  /*
384  * Note that the essentially useless id column in the following
385  * table is required for backwards compatibility. Otherwise, the
386  * name column could be the primary key.
387  */
388  stmt.execute("CREATE TABLE db_info (id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
389  stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.SCHEMA_MAJOR_VERSION_KEY + "', '" + CURRENT_DB_SCHEMA_VERSION.getMajor() + "')");
390  stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.SCHEMA_MINOR_VERSION_KEY + "', '" + CURRENT_DB_SCHEMA_VERSION.getMinor() + "')");
391  stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.CREATION_SCHEMA_MAJOR_VERSION_KEY + "', '" + CURRENT_DB_SCHEMA_VERSION.getMajor() + "')");
392  stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.CREATION_SCHEMA_MINOR_VERSION_KEY + "', '" + CURRENT_DB_SCHEMA_VERSION.getMinor() + "')");
393 
394  // Create a separate instance and reference table for each artifact type
396 
397  String reference_type_dbname;
398  String instance_type_dbname;
399  for (CorrelationAttributeInstance.Type type : DEFAULT_CORRELATION_TYPES) {
400  reference_type_dbname = EamDbUtil.correlationTypeToReferenceTableName(type);
401  instance_type_dbname = EamDbUtil.correlationTypeToInstanceTableName(type);
402 
403  stmt.execute(String.format(createArtifactInstancesTableTemplate, instance_type_dbname, instance_type_dbname));
404  stmt.execute(String.format(instancesCaseIdIdx, instance_type_dbname, instance_type_dbname));
405  stmt.execute(String.format(instancesDatasourceIdIdx, instance_type_dbname, instance_type_dbname));
406  stmt.execute(String.format(instancesValueIdx, instance_type_dbname, instance_type_dbname));
407  stmt.execute(String.format(instancesKnownStatusIdx, instance_type_dbname, instance_type_dbname));
408  stmt.execute(String.format(instancesObjectIdIdx, instance_type_dbname, instance_type_dbname));
409 
410  // FUTURE: allow more than the FILES type
411  if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
412  stmt.execute(String.format(createReferenceTypesTableTemplate.toString(), reference_type_dbname, reference_type_dbname));
413  stmt.execute(String.format(referenceTypesIdx1, reference_type_dbname, reference_type_dbname));
414  stmt.execute(String.format(referenceTypesIdx2, reference_type_dbname, reference_type_dbname));
415  }
416  }
417  } catch (SQLException ex) {
418  LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS
419  return false;
420  } catch (EamDbException ex) {
421  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
422  return false;
423  } finally {
425  }
426  return true;
427  }
428 
436  static String getCreateArtifactInstancesTableTemplate() {
437  // Each "%s" will be replaced with the relevant TYPE_instances table name.
438  StringBuilder createArtifactInstancesTableTemplate = new StringBuilder();
439  createArtifactInstancesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s (");
440  createArtifactInstancesTableTemplate.append("id integer primary key autoincrement NOT NULL,");
441  createArtifactInstancesTableTemplate.append("case_id integer NOT NULL,");
442  createArtifactInstancesTableTemplate.append("data_source_id integer NOT NULL,");
443  createArtifactInstancesTableTemplate.append("value text NOT NULL,");
444  createArtifactInstancesTableTemplate.append("file_path text NOT NULL,");
445  createArtifactInstancesTableTemplate.append("known_status integer NOT NULL,");
446  createArtifactInstancesTableTemplate.append("comment text,");
447  createArtifactInstancesTableTemplate.append("file_obj_id integer,");
448  createArtifactInstancesTableTemplate.append("CONSTRAINT %s_multi_unique UNIQUE(data_source_id, value, file_path) ON CONFLICT IGNORE,");
449  createArtifactInstancesTableTemplate.append("foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,");
450  createArtifactInstancesTableTemplate.append("foreign key (data_source_id) references data_sources(id) ON UPDATE SET NULL ON DELETE SET NULL");
451  createArtifactInstancesTableTemplate.append(")");
452  return createArtifactInstancesTableTemplate.toString();
453  }
454 
463  static String getAddCaseIdIndexTemplate() {
464  // Each "%s" will be replaced with the relevant TYPE_instances table name.
465  return "CREATE INDEX IF NOT EXISTS %s_case_id ON %s (case_id)";
466  }
467 
476  static String getAddDataSourceIdIndexTemplate() {
477  // Each "%s" will be replaced with the relevant TYPE_instances table name.
478  return "CREATE INDEX IF NOT EXISTS %s_data_source_id ON %s (data_source_id)";
479  }
480 
489  static String getAddValueIndexTemplate() {
490  // Each "%s" will be replaced with the relevant TYPE_instances table name.
491  return "CREATE INDEX IF NOT EXISTS %s_value ON %s (value)";
492  }
493 
502  static String getAddKnownStatusIndexTemplate() {
503  // Each "%s" will be replaced with the relevant TYPE_instances table name.
504  return "CREATE INDEX IF NOT EXISTS %s_value_known_status ON %s (value, known_status)";
505  }
506 
515  static String getAddObjectIdIndexTemplate() {
516  // Each "%s" will be replaced with the relevant TYPE_instances table name.
517  return "CREATE INDEX IF NOT EXISTS %s_file_obj_id ON %s (file_obj_id)";
518  }
519 
520  public boolean insertDefaultDatabaseContent() {
521  Connection conn = getEphemeralConnection();
522  if (null == conn) {
523  return false;
524  }
525 
526  boolean result = EamDbUtil.insertDefaultCorrelationTypes(conn) && EamDbUtil.insertDefaultOrganization(conn);
528  return result;
529  }
530 
531  boolean isChanged() {
532  String dbNameString = ModuleSettings.getConfigSetting("CentralRepository", "db.sqlite.dbName"); // NON-NLS
533  String dbDirectoryString = ModuleSettings.getConfigSetting("CentralRepository", "db.sqlite.dbDirectory"); // NON-NLS
534  String bulkThresholdString = ModuleSettings.getConfigSetting("CentralRepository", "db.sqlite.bulkThreshold"); // NON-NLS
535 
536  return !dbName.equals(dbNameString)
537  || !dbDirectory.equals(dbDirectoryString)
538  || !Integer.toString(bulkThreshold).equals(bulkThresholdString);
539  }
540 
544  public String getDbName() {
545  return dbName;
546  }
547 
553  public void setDbName(String dbName) throws EamDbException {
554  if (dbName == null || dbName.isEmpty()) {
555  throw new EamDbException("Invalid database file name. Cannot be null or empty."); // NON-NLS
556  } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) {
557  throw new EamDbException("Invalid database file name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'."); // NON-NLS
558  }
559 
560  this.dbName = dbName;
561  }
562 
566  int getBulkThreshold() {
567  return bulkThreshold;
568  }
569 
573  void setBulkThreshold(int bulkThreshold) throws EamDbException {
574  if (bulkThreshold > 0) {
575  this.bulkThreshold = bulkThreshold;
576  } else {
577  throw new EamDbException("Invalid bulk threshold."); // NON-NLS
578  }
579  }
580 
584  public String getDbDirectory() {
585  return dbDirectory;
586  }
587 
595  public void setDbDirectory(String dbDirectory) throws EamDbException {
596  if (dbDirectory != null && !dbDirectory.isEmpty()) {
597  this.dbDirectory = dbDirectory;
598  } else {
599  throw new EamDbException("Invalid directory for sqlite database. Cannot empty"); // NON-NLS
600  }
601  }
602 
608  public String getFileNameWithPath() {
609  return getDbDirectory() + File.separator + getDbName();
610  }
611 
615  String getDriver() {
616  return JDBC_DRIVER;
617  }
618 
622  String getValidationQuery() {
623  return VALIDATION_QUERY;
624  }
625 
629  String getJDBCBaseURI() {
630  return JDBC_BASE_URI;
631  }
632 
633 }
static String correlationTypeToInstanceTableName(CorrelationAttributeInstance.Type type)
Definition: EamDbUtil.java:325
static boolean executeValidationQuery(Connection conn, String validationQuery)
Definition: EamDbUtil.java:297
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
static boolean insertDefaultCorrelationTypes(Connection conn)
Definition: EamDbUtil.java:102
static String getConfigSetting(String moduleName, String settingName)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static String correlationTypeToReferenceTableName(CorrelationAttributeInstance.Type type)
Definition: EamDbUtil.java:336

Copyright © 2012-2018 Basis Technology. Generated on: Tue Dec 18 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.