X-Git-Url: http://jaekl.net/gitweb/?p=cfb.git;a=blobdiff_plain;f=prod%2Fnet%2Fjaekl%2Fcfb%2Fstore%2FDbStore.java;h=ed22291387c14c8047593d7b1a11932633df6361;hp=7591c88d5ef8633ee4cfeafbd3a94b10070528a1;hb=e8190c8189a5270ada70aaa478409db6dbf1efae;hpb=598968590bf67cf87d3243878f7ebb2ff8015065 diff --git a/prod/net/jaekl/cfb/store/DbStore.java b/prod/net/jaekl/cfb/store/DbStore.java index 7591c88..ed22291 100644 --- a/prod/net/jaekl/cfb/store/DbStore.java +++ b/prod/net/jaekl/cfb/store/DbStore.java @@ -3,18 +3,24 @@ package net.jaekl.cfb.store; import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import java.util.Locale; +import net.jaekl.cfb.CfbBundle; import net.jaekl.cfb.analyze.Analysis; import net.jaekl.cfb.db.CfbSchema; import net.jaekl.cfb.db.Column; import net.jaekl.cfb.db.Condition; import net.jaekl.cfb.db.Operation; import net.jaekl.cfb.db.Row; +import net.jaekl.cfb.db.Sort; import net.jaekl.cfb.db.Table; import net.jaekl.cfb.db.TypeMismatchException; import net.jaekl.cfb.db.driver.DbDriver; +import net.jaekl.cfb.xml.BugCollection; import net.jaekl.cfb.xml.BugInstance; -import net.jaekl.cfb.xml.SourceLine; +import net.jaekl.cfb.xml.LocalVariable; +import net.jaekl.cfb.xml.messages.BugCategory; +import net.jaekl.cfb.xml.messages.BugPattern; import net.jaekl.cfb.xml.messages.MessageCollection; public class DbStore { @@ -27,8 +33,22 @@ public class DbStore { m_driver = driver; m_msgColl = msgColl; } + + public Analysis getPrior(Analysis analysis) throws SQLException, TypeMismatchException { + if (null == analysis) { + return null; + } + Long priorId = getPriorId(analysis); + if (null == priorId) { + return null; + } + + return getAnalysis(priorId); + } - public boolean put(Analysis analysis) throws SQLException { + public boolean put(Analysis analysis) throws SQLException, TypeMismatchException, StoreException { + CfbBundle bundle = CfbBundle.getInst(Locale.getDefault()); + if (null == analysis) { return false; } @@ -40,6 +60,7 @@ public class DbStore { Object[][] values = { { Long.valueOf(runId), + analysis.getProjectName(), analysis.getBuildNumber(), analysis.getStart(), analysis.getEnd() @@ -59,47 +80,103 @@ public class DbStore { int row = 0; for (BugInstance bug : bugs) { - long foundId = m_driver.nextVal(m_con, CfbSchema.FOUND_SEQ); - long bugId = m_msgColl.getPattern(bug.getType()).getId(); - // values[row] = { foundId, bugId, firstLocId, secondLocId, thirdLocId }; + Long foundId = Long.valueOf(m_driver.nextVal(m_con, CfbSchema.FOUND_SEQ)); + Long bugId = Long.valueOf(m_msgColl.getPattern(bug.getType()).getId()); + Long categoryId = Long.valueOf(m_msgColl.getCategory(bug.getCategory()).getId()); + List locs = bug.getLocations(); + Location firstLoc = (locs.size() > 0) ? locs.get(0) : null; + Location secondLoc = (locs.size() > 1) ? locs.get(1) : null; + Location thirdLoc = (locs.size() > 2) ? locs.get(2) : null; + + if (BugPattern.UNKNOWN.getId() == bugId) { + throw new StoreException(bundle.get(CfbBundle.BUG_TYPE_UNKNOWN, ""+bug.getType())); + } + if (BugCategory.UNKNOWN.getId() == categoryId) { + throw new StoreException(bundle.get(CfbBundle.BUG_CATEGORY_UNKNOWN, ""+bug.getCategory())); + } + + values[row][0] = foundId; + values[row][1] = runId; + values[row][2] = bugId; + values[row][3] = categoryId; + values[row][4] = getLocId(firstLoc); + values[row][5] = getLocId(secondLoc); + values[row][6] = getLocId(thirdLoc); + values[row][7] = getVarId(bug); row++; } - return true; + count = m_driver.insert(m_con, CfbSchema.FOUND, values); + return (bugs.size() == count); + } + + String getBugType(Long bugPatternId) throws SQLException, TypeMismatchException + { + Column[] columns = { CfbSchema.TYPE }; + Table[] tables = { CfbSchema.BUGS }; + Condition[] conditions = { new Condition(CfbSchema.BUGID, bugPatternId, Operation.EQUAL) }; + Row row = m_driver.selectExactlyOne(m_con, columns, tables, conditions); + String type = row.getString(0); + return type; + } + + String getCategoryName(Long categoryId) throws SQLException, TypeMismatchException + { + Column[] columns = { CfbSchema.CATEGORY }; + Table[] tables = { CfbSchema.CATEGORIES }; + Condition[] conditions = { new Condition(CfbSchema.CATEGORYID, categoryId, Operation.EQUAL) }; + Row row = m_driver.selectExactlyOne(m_con, columns, tables, conditions); + String name = row.getString(0); + return name; } - Location[] computeLocations(BugInstance bug) + + Location getLoc(Long locId) throws SQLException, TypeMismatchException { - throw new UnsupportedOperationException("UNIMPLEMENTED"); + if (null == locId) { + return null; + } + + Column[] columns = { CfbSchema.CLASSNAME, CfbSchema.METHODNAME, CfbSchema.METHODROLE, CfbSchema.STARTLINE, CfbSchema.ENDLINE }; + Table[] tables = { CfbSchema.LOCATIONS }; + Condition[] conditions = { new Condition(CfbSchema.LOCID, locId, Operation.EQUAL) }; + + Row row = m_driver.selectExactlyOne(m_con, columns, tables, conditions); + + String className = row.getString(0); + String methodName = row.getString(1); + String methodRole = row.getString(2); + Integer startLine = row.getInt(3); + Integer endLine = row.getInt(4); + + Location loc = new Location(locId, className, methodName, methodRole, startLine, endLine); + return loc; } - long getLocId(SourceLine loc) throws SQLException, TypeMismatchException + Long getLocId(Location loc) throws SQLException, TypeMismatchException { - long locId = findLocId(loc); - if (locId >= 0) { + if (null == loc) { + return null; + } + Long locId = findLocId(loc); + if (null != locId) { return locId; } return storeLoc(loc); } - long findLocId(SourceLine loc) throws SQLException, TypeMismatchException + Long findLocId(Location loc) throws SQLException, TypeMismatchException { - Column[] columns = { CfbSchema.LOCATIONS.getColumn(CfbSchema.LOCID) }; + Column[] columns = { CfbSchema.LOCID }; Table[] tables = { CfbSchema.LOCATIONS }; + Condition[] conditions = { - new Condition( CfbSchema.LOCATIONS.getColumn(CfbSchema.CLASSNAME), - loc.getClassName(), - Operation.EQUAL - ), - new Condition( CfbSchema.LOCATIONS.getColumn(CfbSchema.STARTLINE), - loc.getStart(), - Operation.EQUAL - ), - new Condition( CfbSchema.LOCATIONS.getColumn(CfbSchema.ENDLINE), - loc.getEnd(), - Operation.EQUAL - ) + new Condition( CfbSchema.CLASSNAME, loc.getClassName(), Operation.EQUAL ), + new Condition( CfbSchema.METHODNAME, loc.getMethodName(), Operation.EQUAL ), + new Condition( CfbSchema.METHODROLE, loc.getMethodRole(), Operation.EQUAL ), + new Condition( CfbSchema.STARTLINE, loc.getStart(), Operation.EQUAL ), + new Condition( CfbSchema.ENDLINE, loc.getEnd(), Operation.EQUAL ) }; List rows = m_driver.select(m_con, columns, tables, conditions); if (rows.size() > 0) { @@ -108,21 +185,205 @@ public class DbStore { return rows.get(0).getLong(0); } - return (-1); // not found + return null; // not found } - long storeLoc(SourceLine loc) throws SQLException + Long storeLoc(Location loc) throws SQLException { long locId = m_driver.nextVal(m_con, CfbSchema.LOC_SEQ); Object[][] values = { { - locId, + Long.valueOf(locId), loc.getClassName(), + loc.getMethodName(), + loc.getMethodRole(), Long.valueOf(loc.getStart()), Long.valueOf(loc.getEnd()) } }; - m_driver.insert(m_con, CfbSchema.LOCATIONS, values); + int count = m_driver.insert(m_con, CfbSchema.LOCATIONS, values); + if (1 != count) { + return null; + } + + return Long.valueOf(locId); + } + + Long getVarId(BugInstance bug) throws SQLException, TypeMismatchException + { + if (null == bug) { + return null; + } + + List vars = bug.getVariables(); + if ((null == vars) || (0 == vars.size())) { + return null; + } + + return getVarId(vars.get(0)); + } + + LocalVariable getVar(Long varId) throws SQLException, TypeMismatchException + { + if (null == varId) { + return null; + } + + Column[] columns = { CfbSchema.NAME, CfbSchema.VARROLE }; + Table[] tables = { CfbSchema.VARIABLES }; + Condition[] conditions = { new Condition(CfbSchema.VARID_PK, varId, Operation.EQUAL) }; + + List result = m_driver.select(m_con, columns, tables, conditions); + if (result.size() < 1) { + throw new SQLException("No variable found for ID " + varId); + } + if (result.size() > 1) { + throw new SQLException("Too many matches (" + result.size() + ") found for variable ID " + varId); + } + + String varName = result.get(0).getString(0); + String varRole = result.get(0).getString(1); + + return new LocalVariable(varId, varName, varRole); + } + + Long getVarId(LocalVariable var) throws SQLException, TypeMismatchException + { + if (null == var) { + return null; + } + + Long result = findVarId(var); + + if (null != result) { + return result; + } + + return storeVar(var); + } + + Long findVarId(LocalVariable var) throws SQLException, TypeMismatchException + { + Column[] columns = { CfbSchema.VARID_PK }; + Table[] tables = { CfbSchema.VARIABLES }; + + Condition[] conditions = { + new Condition( CfbSchema.NAME, var.getName(), Operation.EQUAL ), + new Condition( CfbSchema.VARROLE, var.getRole(), Operation.EQUAL ) + }; + List rows = m_driver.select(m_con, columns, tables, conditions); + if (rows.size() > 0) { + assert(1 == rows.size()); // should only have one match + + return rows.get(0).getLong(0); + } + + return null; // not found + } + + Long storeVar(LocalVariable var) throws SQLException + { + long varId = m_driver.nextVal(m_con, CfbSchema.VARIABLE_SEQ); + + Object[][] values = { { + Long.valueOf(varId), + var.getName(), + var.getRole() + } }; + int count = m_driver.insert(m_con, CfbSchema.VARIABLES, values); + if (1 != count) { + return null; + } + + return Long.valueOf(varId); + } + + Long getPriorId(Analysis analysis) throws SQLException, TypeMismatchException + { + Column[] columns = { CfbSchema.RUNID }; + Table[] tables = { CfbSchema.RUNS }; + Condition[] conditions = { + new Condition( CfbSchema.PROJNAME, analysis.getProjectName(), Operation.EQUAL ), + new Condition( CfbSchema.STARTTIME, analysis.getStart(), Operation.LESS_THAN ) + }; + Sort[] sorts = { new Sort( CfbSchema.STARTTIME, Sort.Direction.DESCENDING ) }; + int limit = 1; + + List rows = m_driver.select(m_con, columns, tables, conditions, sorts, limit); + if (rows.size() < 1) { + return null; + } + return rows.get(0).getLong(0); + } + + Analysis getAnalysis(Long analysisId) throws SQLException, TypeMismatchException + { + Column[] columns = { CfbSchema.PROJNAME, CfbSchema.VERSION, CfbSchema.STARTTIME, CfbSchema.ENDTIME }; + Table[] tables = { CfbSchema.RUNS }; + Condition[] conditions = { new Condition( CfbSchema.RUNID, analysisId, Operation.EQUAL ) }; + + List rows = m_driver.select(m_con, columns, tables, conditions); + if (rows.size() < 1) { + return null; + } + + Row row = rows.get(0); + + String projName = row.getString(0); + String version = row.getString(1); + java.util.Date start= row.getDate(2); + java.util.Date end = row.getDate(3); + + Analysis prior = new Analysis(projName, version); + prior.setId(analysisId.longValue()); + prior.setStart(start); + prior.setEnd(end); + + prior.setBugCollection(getBugCollection(analysisId)); + + return prior; + } + + BugCollection getBugCollection(Long runId) throws SQLException, TypeMismatchException + { + Column[] columns = { + CfbSchema.FOUNDID, + CfbSchema.BUGID, + CfbSchema.CATEGORYID, + CfbSchema.FIRSTLOCID, + CfbSchema.SECONDLOCID, + CfbSchema.THIRDLOCID, + CfbSchema.VARID_FK + }; + Table[] tables = { + CfbSchema.FOUND + }; + Condition[] conditions = { + new Condition(CfbSchema.RUNID, runId, Operation.EQUAL) + }; + + BugCollection coll = new BugCollection(); + + List rows = m_driver.select(m_con, columns, tables, conditions); + + for (Row row : rows) { + // long foundId = row.getLong(0); + Long bugId = row.getLong(1); + Long categoryId = row.getLong(2); + Long firstLocId = row.getLong(3); + Long secondLocId = row.getLong(4); + Long thirdLocId = row.getLong(5); + Long varId = row.getLong(6); + + String bugType = getBugType(bugId); + String category = getCategoryName(categoryId); + Location[] locations = { getLoc(firstLocId), getLoc(secondLocId), getLoc(thirdLocId) }; + LocalVariable[] vars = { getVar(varId) }; + + + BugInstance bug = new BugInstance(bugId, category, bugType, locations, vars); + coll.add(bug); + } - return locId; + return coll; } }