GT-3294 Added support for DB FixedField with improved indexing.

This commit is contained in:
ghidra1 2020-02-24 18:02:01 -05:00
parent 14d4c87ef4
commit fcb3151f94
224 changed files with 9574 additions and 7913 deletions

View file

@ -0,0 +1,65 @@
/* ###
* IP: GHIDRA
*
* 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 ghidra.feature.vt.api.db;
import db.Field;
public class TableColumn {
private final Field columnField;
private boolean indexed;
private int ordinal;
private String name;
public TableColumn(Field columnField) {
this(columnField, false);
}
public TableColumn(Field columnField, boolean isIndexed) {
this.columnField = columnField;
indexed = isIndexed;
}
void setName(String name) {
this.name = name;
}
void setOrdinal(int ordinal) {
this.ordinal = ordinal;
}
public boolean isIndexed() {
return indexed;
}
public Field getColumnField() {
return columnField;
}
public String name() {
return name;
}
public int column() {
return ordinal;
}
@Override
public String toString() {
return name() + "(" + ordinal + ")";
}
}

View file

@ -0,0 +1,94 @@
/* ###
* IP: GHIDRA
*
* 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 ghidra.feature.vt.api.db;
import java.util.*;
import db.Field;
import ghidra.util.Msg;
public class TableDescriptor {
private TableColumn[] columns;
protected TableDescriptor() {
this.columns = discoverTableColumns();
}
private TableColumn[] discoverTableColumns() {
Class<? extends TableDescriptor> clazz = getClass();
java.lang.reflect.Field[] fields = clazz.getFields();
List<TableColumn> list = new ArrayList<TableColumn>(fields.length);
for (java.lang.reflect.Field field : fields) {
Class<?> type = field.getType();
if (!TableColumn.class.isAssignableFrom(type)) {
continue;
}
try {
TableColumn column = (TableColumn) field.get(null);
column.setName(field.getName());
column.setOrdinal(list.size());
list.add(column);
}
catch (IllegalArgumentException e) {
// shouldn't happen
}
catch (IllegalAccessException e) {
Msg.showError(this, null, "Class Usage Error",
"You must provide public " + "static members for your TableColumns");
}
}
return list.toArray(new TableColumn[list.size()]);
}
public int[] getIndexedColumns() {
int count = 0;
for (TableColumn column : columns) {
if (column.isIndexed()) {
count++;
}
}
int[] indexedColumns = new int[count];
count = 0;
for (TableColumn column : columns) {
if (column.isIndexed()) {
indexedColumns[count++] = column.column();
}
}
return indexedColumns;
}
public String[] getColumnNames() {
List<String> list = new LinkedList<String>();
for (TableColumn column : columns) {
list.add(column.name());
}
return list.toArray(new String[columns.length]);
}
public Field[] getColumnFields() {
Field[] fields = new Field[columns.length];
for (int i = 0; i < fields.length; i++) {
fields[i] = columns[i].getColumnField().newField();
}
return fields;
}
}

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,48 +16,50 @@
package ghidra.feature.vt.api.db;
import static ghidra.feature.vt.api.db.VTAddressCorrelatorAdapter.AddressCorrelationTableDescriptor.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
import java.io.File;
import java.io.IOException;
import java.util.List;
import db.*;
import db.util.TableColumn;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
public abstract class VTAddressCorrelatorAdapter {
public static class AddressCorrelationTableDescriptor extends db.util.TableDescriptor {
public static class AddressCorrelationTableDescriptor
extends ghidra.feature.vt.api.db.TableDescriptor {
public static TableColumn SOURCE_ENTRY_COL = new TableColumn(LongField.class, true);
public static TableColumn SOURCE_ADDRESS_COL = new TableColumn(LongField.class);
public static TableColumn DESTINATION_ADDRESS_COL = new TableColumn(LongField.class);
public static AddressCorrelationTableDescriptor INSTANCE = new AddressCorrelationTableDescriptor();
public static TableColumn SOURCE_ENTRY_COL = new TableColumn(LongField.INSTANCE, true);
public static TableColumn SOURCE_ADDRESS_COL = new TableColumn(LongField.INSTANCE);
public static TableColumn DESTINATION_ADDRESS_COL = new TableColumn(LongField.INSTANCE);
public static AddressCorrelationTableDescriptor INSTANCE =
new AddressCorrelationTableDescriptor();
}
static String TABLE_NAME = "AddressCorrelationTable";
static Schema TABLE_SCHEMA = new Schema(0, "Key",
INSTANCE.getColumnClasses(), INSTANCE.getColumnNames());
static Schema TABLE_SCHEMA =
new Schema(0, "Key", INSTANCE.getColumnFields(), INSTANCE.getColumnNames());
static int[] TABLE_INDEXES = INSTANCE.getIndexedColumns();
private DBHandle dbHandle;
protected VTAddressCorrelatorAdapter(DBHandle dbHandle) {
this.dbHandle = dbHandle;
}
public static VTAddressCorrelatorAdapter createAdapter(DBHandle dbHandle) throws IOException {
return new VTAddressCorrelationAdapterV0(dbHandle);
}
public static VTAddressCorrelatorAdapter getAdapter(DBHandle dbHandle, TaskMonitor monitor)
public static VTAddressCorrelatorAdapter getAdapter(DBHandle dbHandle, TaskMonitor monitor)
throws VersionException {
return new VTAddressCorrelationAdapterV0(dbHandle, monitor);
}
abstract void createAddressRecord(long sourceEntryLong, long sourceLong, long destinationLong) throws IOException;
abstract void createAddressRecord(long sourceEntryLong, long sourceLong, long destinationLong)
throws IOException;
abstract List<Record> getAddressRecords(long sourceEntryLong) throws IOException;
@ -69,8 +70,9 @@ public abstract class VTAddressCorrelatorAdapter {
void save(TaskMonitor monitor) throws CancelledException, IOException {
dbHandle.save("", null, monitor);
}
void saveAs(File file, TaskMonitor monitor) throws CancelledException, IOException {
dbHandle.saveAs(file, true, monitor);
}
}

View file

@ -1,21 +0,0 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* 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 ghidra.feature.vt.api.db;
public class VTAppliedMarkupTableDBAdapterV0 {
}

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,35 +15,36 @@
*/
package ghidra.feature.vt.api.db;
import static ghidra.feature.vt.api.db.VTAssociationTableDBAdapter.AssociationTableDescriptor.INSTANCE;
import ghidra.feature.vt.api.main.VTAssociationStatus;
import ghidra.feature.vt.api.main.VTAssociationType;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
import static ghidra.feature.vt.api.db.VTAssociationTableDBAdapter.AssociationTableDescriptor.*;
import java.io.IOException;
import java.util.Set;
import db.*;
import db.util.TableColumn;
import ghidra.feature.vt.api.main.VTAssociationStatus;
import ghidra.feature.vt.api.main.VTAssociationType;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
public abstract class VTAssociationTableDBAdapter {
public static class AssociationTableDescriptor extends db.util.TableDescriptor {
public static class AssociationTableDescriptor
extends ghidra.feature.vt.api.db.TableDescriptor {
public static TableColumn SOURCE_ADDRESS_COL = new TableColumn(LongField.class, true);
public static TableColumn DESTINATION_ADDRESS_COL = new TableColumn(LongField.class, true);
public static TableColumn TYPE_COL = new TableColumn(ByteField.class);
public static TableColumn STATUS_COL = new TableColumn(ByteField.class);
public static TableColumn APPLIED_STATUS_COL = new TableColumn(ByteField.class);
public static TableColumn VOTE_COUNT_COL = new TableColumn(IntField.class);
public static TableColumn SOURCE_ADDRESS_COL = new TableColumn(LongField.INSTANCE, true);
public static TableColumn DESTINATION_ADDRESS_COL =
new TableColumn(LongField.INSTANCE, true);
public static TableColumn TYPE_COL = new TableColumn(ByteField.INSTANCE);
public static TableColumn STATUS_COL = new TableColumn(ByteField.INSTANCE);
public static TableColumn APPLIED_STATUS_COL = new TableColumn(ByteField.INSTANCE);
public static TableColumn VOTE_COUNT_COL = new TableColumn(IntField.INSTANCE);
public static AssociationTableDescriptor INSTANCE = new AssociationTableDescriptor();
}
static String TABLE_NAME = "AssociationTable";
static Schema TABLE_SCHEMA =
new Schema(0, "Key", INSTANCE.getColumnClasses(), INSTANCE.getColumnNames());
new Schema(0, "Key", INSTANCE.getColumnFields(), INSTANCE.getColumnNames());
static int[] TABLE_INDEXES = INSTANCE.getIndexedColumns();
public static VTAssociationTableDBAdapter createAdapter(DBHandle dbHandle) throws IOException {

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,36 +15,35 @@
*/
package ghidra.feature.vt.api.db;
import static ghidra.feature.vt.api.db.VTMatchMarkupItemTableDBAdapter.MarkupTableDescriptor.INSTANCE;
import ghidra.feature.vt.api.impl.MarkupItemStorage;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
import static ghidra.feature.vt.api.db.VTMatchMarkupItemTableDBAdapter.MarkupTableDescriptor.*;
import java.io.IOException;
import db.*;
import db.util.TableColumn;
import ghidra.feature.vt.api.impl.MarkupItemStorage;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
public abstract class VTMatchMarkupItemTableDBAdapter {
public static class MarkupTableDescriptor extends db.util.TableDescriptor {
public static TableColumn ASSOCIATION_KEY_COL = new TableColumn(LongField.class, true);
public static TableColumn ADDRESS_SOURCE_COL = new TableColumn(StringField.class);
public static TableColumn DESTINATION_ADDRESS_COL = new TableColumn(LongField.class);
public static TableColumn MARKUP_TYPE_COL = new TableColumn(ShortField.class);
public static TableColumn SOURCE_ADDRESS_COL = new TableColumn(LongField.class);
public static TableColumn SOURCE_VALUE_COL = new TableColumn(StringField.class);
public static class MarkupTableDescriptor extends ghidra.feature.vt.api.db.TableDescriptor {
public static TableColumn ASSOCIATION_KEY_COL = new TableColumn(LongField.INSTANCE, true);
public static TableColumn ADDRESS_SOURCE_COL = new TableColumn(StringField.INSTANCE);
public static TableColumn DESTINATION_ADDRESS_COL = new TableColumn(LongField.INSTANCE);
public static TableColumn MARKUP_TYPE_COL = new TableColumn(ShortField.INSTANCE);
public static TableColumn SOURCE_ADDRESS_COL = new TableColumn(LongField.INSTANCE);
public static TableColumn SOURCE_VALUE_COL = new TableColumn(StringField.INSTANCE);
public static TableColumn ORIGINAL_DESTINATION_VALUE_COL =
new TableColumn(StringField.class);
public static TableColumn STATUS_COL = new TableColumn(ByteField.class);
public static TableColumn STATUS_DESCRIPTION_COL = new TableColumn(StringField.class);
new TableColumn(StringField.INSTANCE);
public static TableColumn STATUS_COL = new TableColumn(ByteField.INSTANCE);
public static TableColumn STATUS_DESCRIPTION_COL = new TableColumn(StringField.INSTANCE);
public static MarkupTableDescriptor INSTANCE = new MarkupTableDescriptor();
}
protected static String TABLE_NAME = "MatchMarkupItemTable";
static Schema TABLE_SCHEMA =
new Schema(0, "Key", INSTANCE.getColumnClasses(), INSTANCE.getColumnNames());
new Schema(0, "Key", INSTANCE.getColumnFields(), INSTANCE.getColumnNames());
protected static int[] INDEXED_COLUMNS = INSTANCE.getIndexedColumns();
@ -71,6 +69,5 @@ public abstract class VTMatchMarkupItemTableDBAdapter {
public abstract int getRecordCount();
public abstract Record createMarkupItemRecord(MarkupItemStorage markupItem)
throws IOException;
public abstract Record createMarkupItemRecord(MarkupItemStorage markupItem) throws IOException;
}

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,34 +15,33 @@
*/
package ghidra.feature.vt.api.db;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import db.*;
import ghidra.feature.vt.api.main.VTProgramCorrelator;
import ghidra.program.database.map.AddressMap;
import ghidra.program.model.address.AddressSet;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import db.*;
public abstract class VTMatchSetTableDBAdapter {
public enum ColumnDescription {
CORRELATOR_CLASS_COL(StringField.class),
CORRELATOR_NAME_COL(StringField.class),
OPTIONS_COL(StringField.class);
CORRELATOR_CLASS_COL(StringField.INSTANCE),
CORRELATOR_NAME_COL(StringField.INSTANCE),
OPTIONS_COL(StringField.INSTANCE);
private final Class<? extends Field> columnClass;
private final Field columnField;
private ColumnDescription(Class<? extends Field> columnClass) {
this.columnClass = columnClass;
private ColumnDescription(Field columnField) {
this.columnField = columnField;
}
public Class<? extends Field> getColumnClass() {
return columnClass;
public Field getColumnField() {
return columnField;
}
public int column() {
@ -59,20 +57,18 @@ public abstract class VTMatchSetTableDBAdapter {
return list.toArray(new String[columns.length]);
}
@SuppressWarnings("unchecked")
// we know our class types are safe
private static Class<? extends Field>[] getColumnClasses() {
private static Field[] getColumnFields() {
ColumnDescription[] columns = ColumnDescription.values();
List<Class<? extends Field>> list = new LinkedList<Class<? extends Field>>();
for (ColumnDescription column : columns) {
list.add(column.getColumnClass());
Field[] fields = new Field[columns.length];
for (int i = 0; i < fields.length; i++) {
fields[i] = columns[i].getColumnField();
}
return list.toArray(new Class[columns.length]);
return fields;
}
}
static String TABLE_NAME = "MatchSetTable";
static Schema TABLE_SCHEMA = new Schema(0, "Key", ColumnDescription.getColumnClasses(),
static Schema TABLE_SCHEMA = new Schema(0, "Key", ColumnDescription.getColumnFields(),
ColumnDescription.getColumnNames());
static VTMatchSetTableDBAdapter createAdapter(DBHandle dbHandle) throws IOException {

View file

@ -16,13 +16,6 @@
package ghidra.feature.vt.api.db;
import static ghidra.feature.vt.api.db.VTMatchSetTableDBAdapter.ColumnDescription.*;
import ghidra.feature.vt.api.main.VTProgramCorrelator;
import ghidra.framework.options.ToolOptions;
import ghidra.program.database.map.AddressMap;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.util.exception.VersionException;
import ghidra.util.xml.GenericXMLOutputter;
import java.io.IOException;
import java.io.StringWriter;
@ -31,13 +24,20 @@ import org.jdom.Element;
import org.jdom.output.XMLOutputter;
import db.*;
import ghidra.feature.vt.api.main.VTProgramCorrelator;
import ghidra.framework.options.ToolOptions;
import ghidra.program.database.map.AddressMap;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.util.exception.VersionException;
import ghidra.util.xml.GenericXMLOutputter;
public class VTMatchSetTableDBAdapterV0 extends VTMatchSetTableDBAdapter {
private Table table;
private static final Schema STORED_ADDRESS_RANGE_SCHEMA = new Schema(0, "Key", new Class[] {
LongField.class, LongField.class }, new String[] { "addr1", "addr2" });
private static final Schema STORED_ADDRESS_RANGE_SCHEMA = new Schema(0, "Key",
new Field[] { LongField.INSTANCE, LongField.INSTANCE }, new String[] { "addr1", "addr2" });
private final DBHandle dbHandle;
@ -46,7 +46,8 @@ public class VTMatchSetTableDBAdapterV0 extends VTMatchSetTableDBAdapter {
table = dbHandle.createTable(TABLE_NAME, TABLE_SCHEMA);
}
public VTMatchSetTableDBAdapterV0(DBHandle dbHandle, OpenMode openMode) throws VersionException {
public VTMatchSetTableDBAdapterV0(DBHandle dbHandle, OpenMode openMode)
throws VersionException {
this.dbHandle = dbHandle;
table = dbHandle.getTable(TABLE_NAME);
if (table == null) {
@ -59,7 +60,8 @@ public class VTMatchSetTableDBAdapterV0 extends VTMatchSetTableDBAdapter {
}
@Override
public Record createMatchSetRecord(long key, VTProgramCorrelator correlator) throws IOException {
public Record createMatchSetRecord(long key, VTProgramCorrelator correlator)
throws IOException {
Record record = TABLE_SCHEMA.createRecord(key);
record.setString(CORRELATOR_CLASS_COL.column(), correlator.getClass().getName());

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,36 +15,35 @@
*/
package ghidra.feature.vt.api.db;
import ghidra.feature.vt.api.main.VTMatchInfo;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import db.*;
import ghidra.feature.vt.api.main.VTMatchInfo;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
public abstract class VTMatchTableDBAdapter {
public enum ColumnDescription {
TAG_KEY_COL(LongField.class),
MATCH_SET_COL(LongField.class),
SIMILARITY_SCORE_COL(StringField.class),
CONFIDENCE_SCORE_COL(StringField.class),
LENGTH_TYPE(StringField.class),
SOURCE_LENGTH_COL(IntField.class),
DESTINATION_LENGTH_COL(IntField.class),
ASSOCIATION_COL(LongField.class);
TAG_KEY_COL(LongField.INSTANCE),
MATCH_SET_COL(LongField.INSTANCE),
SIMILARITY_SCORE_COL(StringField.INSTANCE),
CONFIDENCE_SCORE_COL(StringField.INSTANCE),
LENGTH_TYPE(StringField.INSTANCE),
SOURCE_LENGTH_COL(IntField.INSTANCE),
DESTINATION_LENGTH_COL(IntField.INSTANCE),
ASSOCIATION_COL(LongField.INSTANCE);
private final Class<? extends Field> columnClass;
private final Field columnField;
private ColumnDescription(Class<? extends Field> columnClass) {
this.columnClass = columnClass;
private ColumnDescription(Field columnField) {
this.columnField = columnField;
}
public Class<? extends Field> getColumnClass() {
return columnClass;
public Field getColumnField() {
return columnField;
}
public int column() {
@ -61,22 +59,19 @@ public abstract class VTMatchTableDBAdapter {
return list.toArray(new String[columns.length]);
}
@SuppressWarnings("unchecked")
// we know our class types are safe
private static Class<? extends Field>[] getColumnClasses() {
private static Field[] getColumnFields() {
ColumnDescription[] columns = ColumnDescription.values();
List<Class<? extends Field>> list = new LinkedList<Class<? extends Field>>();
for (ColumnDescription column : columns) {
list.add(column.getColumnClass());
Field[] fields = new Field[columns.length];
for (int i = 0; i < fields.length; i++) {
fields[i] = columns[i].getColumnField();
}
return list.toArray(new Class[columns.length]);
return fields;
}
}
static String TABLE_NAME = "MatchTable";
static Schema TABLE_SCHEMA =
new Schema(0, "Key", ColumnDescription.getColumnClasses(),
ColumnDescription.getColumnNames());
static Schema TABLE_SCHEMA = new Schema(0, "Key", ColumnDescription.getColumnFields(),
ColumnDescription.getColumnNames());
static VTMatchTableDBAdapter createAdapter(DBHandle dbHandle, long tableID) throws IOException {
return new VTMatchTableDBAdapterV0(dbHandle, tableID);

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,14 +15,13 @@
*/
package ghidra.feature.vt.api.db;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import db.*;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
/**
* Abstract adapter for the database table that holds tags for version tracking matches.
@ -31,16 +29,16 @@ import db.*;
public abstract class VTMatchTagDBAdapter {
public enum ColumnDescription {
TAG_NAME_COL(StringField.class);
TAG_NAME_COL(StringField.INSTANCE);
private final Class<? extends Field> columnClass;
private final Field columnField;
private ColumnDescription(Class<? extends Field> columnClass) {
this.columnClass = columnClass;
private ColumnDescription(Field columnField) {
this.columnField = columnField;
}
public Class<? extends Field> getColumnClass() {
return columnClass;
public Field getColumnField() {
return columnField;
}
public int column() {
@ -56,22 +54,19 @@ public abstract class VTMatchTagDBAdapter {
return list.toArray(new String[columns.length]);
}
@SuppressWarnings("unchecked")
// we know our class types are safe
private static Class<? extends Field>[] getColumnClasses() {
private static Field[] getColumnFields() {
ColumnDescription[] columns = ColumnDescription.values();
List<Class<? extends Field>> list = new LinkedList<Class<? extends Field>>();
for (ColumnDescription column : columns) {
list.add(column.getColumnClass());
Field[] fields = new Field[columns.length];
for (int i = 0; i < fields.length; i++) {
fields[i] = columns[i].getColumnField();
}
return list.toArray(new Class[columns.length]);
return fields;
}
}
static String TABLE_NAME = "MatchTagTable";
static Schema TABLE_SCHEMA =
new Schema(0, LongField.class, "Key", ColumnDescription.getColumnClasses(),
ColumnDescription.getColumnNames());
static Schema TABLE_SCHEMA = new Schema(0, "Key", ColumnDescription.getColumnFields(),
ColumnDescription.getColumnNames());
static VTMatchTagDBAdapter createAdapter(DBHandle dbHandle) throws IOException {
return new VTMatchTagDBAdapterV0(dbHandle);

View file

@ -39,10 +39,10 @@ import ghidra.util.exception.*;
import ghidra.util.task.*;
public class VTSessionDB extends DomainObjectAdapterDB implements VTSession, VTChangeManager {
private final static Class<?>[] COL_CLASS = new Class[] { StringField.class };
private final static Field[] COL_FIELDS = new Field[] { StringField.INSTANCE };
private final static String[] COL_TYPES = new String[] { "Value" };
private final static Schema SCHEMA =
new Schema(0, StringField.class, "Key", COL_CLASS, COL_TYPES);
new Schema(0, StringField.INSTANCE, "Key", COL_FIELDS, COL_TYPES);
private static final String PROGRAM_ID_PROPERTYLIST_NAME = "ProgramIDs";
private static final String SOURCE_PROGRAM_ID_PROPERTY_KEY = "SourceProgramID";
@ -55,7 +55,24 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession, VTC
private static final long IMPLIED_MATCH_SET_ID = -1;
private static final String PROPERTY_TABLE_NAME = "PropertyTable";
private static final String DB_VERSION_PROPERTY_NAME = "DB_VERSION";
private static final int DB_VERSION = 1;
/**
* DB_VERSION should be incremented any time a change is made to the overall
* database schema associated with any of the adapters.
* 14-Nov-2019 - version 2 - Corrected fixed length indexing implementation causing
* change in index table low-level storage for newly
* created tables.
*/
private static final int DB_VERSION = 2;
/**
* UPGRADE_REQUIRED_BFORE_VERSION should be changed to DB_VERSION any time the
* latest version requires a forced upgrade (i.e., Read-only mode not supported
* until upgrade is performed). It is assumed that read-only mode is supported
* if the data's version is >= UPGRADE_REQUIRED_BEFORE_VERSION and <= DB_VERSION.
*/
// NOTE: Schema upgrades are not currently supported
private static final int UPGRADE_REQUIRED_BEFORE_VERSION = 1;
private VTMatchSetTableDBAdapter matchSetTableAdapter;
private AssociationDatabaseManager associationManager;
@ -78,12 +95,11 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession, VTC
int ID = session.startTransaction("Constructing New Version Tracking Match Set");
try {
session.propertyTable = createPropertyTable(session.getDBHandle());
session.matchSetTableAdapter =
VTMatchSetTableDBAdapter.createAdapter(session.getDBHandle());
session.propertyTable = session.dbh.createTable(PROPERTY_TABLE_NAME, SCHEMA);
session.matchSetTableAdapter = VTMatchSetTableDBAdapter.createAdapter(session.dbh);
session.associationManager =
AssociationDatabaseManager.createAssociationManager(session.getDBHandle(), session);
session.matchTagAdapter = VTMatchTagDBAdapter.createAdapter(session.getDBHandle());
AssociationDatabaseManager.createAssociationManager(session.dbh, session);
session.matchTagAdapter = VTMatchTagDBAdapter.createAdapter(session.dbh);
session.initializePrograms(sourceProgram, destinationProgram);
session.createMatchSet(
new ManualMatchProgramCorrelator(sourceProgram, destinationProgram),
@ -91,6 +107,7 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession, VTC
session.createMatchSet(
new ImpliedMatchProgramCorrelator(sourceProgram, destinationProgram),
IMPLIED_MATCH_SET_ID);
session.updateVersion();
}
finally {
session.endTransaction(ID, true);
@ -105,21 +122,29 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession, VTC
return session;
}
private static Table createPropertyTable(DBHandle dbh) throws IOException {
Table table = dbh.createTable(PROPERTY_TABLE_NAME, SCHEMA);
private void updateVersion() throws IOException {
Record record = SCHEMA.createRecord(new StringField(DB_VERSION_PROPERTY_NAME));
record.setString(0, Integer.toString(DB_VERSION));
table.putRecord(record);
return table;
propertyTable.putRecord(record);
}
public static VTSessionDB getVTSession(DBHandle dbHandle, OpenMode openMode, Object consumer,
TaskMonitor monitor) throws VersionException, IOException {
VTSessionDB session = new VTSessionDB(dbHandle, consumer);
if (session.getVersion() < DB_VERSION) {
throw new VersionException("Version Tracking Sessions do not support upgrades.");
int storedVersion = session.getVersion();
if (storedVersion > DB_VERSION) {
throw new VersionException(VersionException.NEWER_VERSION, false);
}
// The following version logic holds true for DB_VERSION=2 which assumes no additional
// DB index tables will be added when open for update/upgrade. This will not hold
// true for future revisions associated with table schema changes in which case the
// UPGRADE_REQUIRED_BEFORE_VERSION value should equal DB_VERSION.
if (storedVersion < UPGRADE_REQUIRED_BEFORE_VERSION) {
throw new VersionException("Version Tracking Sessions do not support schema upgrades.");
}
session.matchSetTableAdapter =
VTMatchSetTableDBAdapter.getAdapter(session.getDBHandle(), openMode, monitor);
session.associationManager =