Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New classes to support EDA analysis migrations #82

Merged
merged 1 commit into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.gusdb.wdk.model.fix.table.edaanalysis;

import java.util.List;

import org.gusdb.wdk.model.WdkModel;
import org.gusdb.wdk.model.fix.table.TableRowInterfaces.TableRowUpdaterPlugin;
import org.gusdb.wdk.model.fix.table.TableRowUpdater;

/**
* Abstract class serves as a base for any plugins that need to
* update/migrate the rows in the EDA analysis table
*/
public abstract class AbstractAnalysisUpdater implements TableRowUpdaterPlugin<AnalysisRow> {

protected WdkModel _wdkModel;
protected boolean _writeToDb = false;

@Override
public void configure(WdkModel wdkModel, List<String> additionalArgs) throws Exception {
_wdkModel = wdkModel;
_writeToDb = additionalArgs.size() > 0 && additionalArgs.get(0).equals("-write");
}

@Override
public TableRowUpdater<AnalysisRow> getTableRowUpdater(WdkModel wdkModel) {
AnalysisRecordFactory factory = new AnalysisRecordFactory();
return new TableRowUpdater<AnalysisRow>(factory, factory, this, wdkModel);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.gusdb.wdk.model.fix.table.edaanalysis;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Collection;

import org.gusdb.fgputil.ListBuilder;
import org.gusdb.fgputil.db.platform.DBPlatform;
import org.gusdb.wdk.model.WdkModel;
import org.gusdb.wdk.model.fix.table.TableRowInterfaces.TableRowFactory;
import org.gusdb.wdk.model.fix.table.TableRowInterfaces.TableRowWriter;

/**
* Provides the read/write mechanisms for updating EDA analysis table rows needed by the
* TableRowUpdater API.
*/
public class AnalysisRecordFactory implements TableRowFactory<AnalysisRow>, TableRowWriter<AnalysisRow> {

private String _schema;

@Override
public String getRecordsSql(String schema, String projectId) {
// reset schema based on project (userdb schema is not where eda data lives
switch(projectId) {
case "ClinEpiDB": _schema = "edauserce"; break;
case "MicrobiomeDB": _schema = "edausermb"; break;
default: _schema = "edauservb"; break;
}
return
"select analysis_id, study_id, analysis_descriptor, num_filters, num_computations, num_visualizations" +
" from " + _schema + ".analysis";
}

@Override
public AnalysisRow newTableRow(ResultSet rs, DBPlatform platform) throws SQLException {
return new AnalysisRow(rs, platform);
}

@Override
public String getWriteSql(String schema) {
return
"update " + _schema + ".analysis (study_id, analysis_descriptor, num_filters, num_computations, num_visualizations)" +
" values (?, ?, ?, ?, ?) where analysis_id = ?";
}

@Override
public Integer[] getParameterTypes() {
return new Integer[] {
Types.VARCHAR,
Types.CLOB,
Types.INTEGER,
Types.INTEGER,
Types.INTEGER,
Types.VARCHAR
};
}

@Override
public Collection<Object[]> toValues(AnalysisRow obj) {
return ListBuilder.asList(obj.toOrderedValues());
}

@Override
public void setUp(WdkModel wdkModel) throws Exception {
// nothing to do here
}

@Override
public void tearDown(WdkModel wdkModel) throws Exception {
// nothing to do here
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.gusdb.wdk.model.fix.table.edaanalysis;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Optional;

import org.gusdb.fgputil.db.platform.DBPlatform;
import org.gusdb.wdk.model.fix.table.TableRowInterfaces.TableRow;
import org.json.JSONArray;
import org.json.JSONObject;

/**
* Stores values of a database row in the EDA analysis table
*/
public class AnalysisRow implements TableRow {

// basic analysis information
private String _analysisId;
private String _datasetId;
private JSONObject _descriptor;

// bookkeeping; update these if values change in descriptor
private int _numFilters;
private int _numComputations;
private int _numVisualizations;

public AnalysisRow(ResultSet rs, DBPlatform platform) throws SQLException {
_analysisId = rs.getString("analysis_id");
_datasetId = rs.getString("study_id");
_descriptor = new JSONObject(platform.getClobData(rs, "analysis_descriptor"));
_numFilters = rs.getInt("num_filters");
_numComputations = rs.getInt("num_computations");
_numVisualizations = rs.getInt("num_visualizations");
}

public Object[] toOrderedValues() {
return new Object[] {
_datasetId, _descriptor.toString(), _numFilters, _numComputations, _numVisualizations, _analysisId
};
}

@Override
public String getDisplayId() {
return _analysisId;
}

public String getDatasetId() {
return _datasetId;
}

/**
* Returns the current descriptor for this analysis. Note this object can be
* edited in-place before returning the row result; however if the number of
* filters, computations, or visualizations is modified, you must also call
* <code>refreshStats()</code> to refresh those counts or they will be inaccurate
* in the database.
*
* @return descriptor for this analysis
*/
public JSONObject getDescriptor() {
return _descriptor;
}

/**
* Sets a new descriptor and refreshes the stats (number of filters, computations,
* and visualizations) on this analysis.
*
* @param descriptor new descriptor
*/
public void setDescriptor(JSONObject descriptor) {
_descriptor = descriptor;
refreshStats();
}

public void refreshStats() {
_numFilters = _descriptor.getJSONObject("subset").getJSONArray("descriptor").length();
JSONArray computations = Optional.ofNullable(_descriptor.optJSONArray("computations")).orElse(new JSONArray());
_numComputations = computations.length();
_numVisualizations = 0;
for (int i = 0; i < _numComputations; i++) {
_numVisualizations += computations.getJSONObject(i).getJSONArray("visualizations").length();
}
}
}
Loading