public void SaveFile(CVSFile oFile) { using (SQLiteConnection oSQLiteConnection = SQLConnection()) { oSQLiteConnection.Open(); //Save File if (oFile.iID == 0) { string sSQL = $@"INSERT INTO Files (ID, Name, Path, CVSPath, LastUpdated, Deleted, Ignored) VALUES (Null, '{oFile.sName.Replace("'", @"''")}', '{oFile.sPath.Replace("'", @"''")}', '{((oFile.sCVSPath != null) ? oFile.sCVSPath.Replace("'", @"''") : "")}', '{oFile.dLastUpdated.ToString("yyyy-MM-dd HH:mm:ss")}', {(oFile.bDeleted ? 1 : 0)}, {(oFile.bIgnored ? 1 : 0)});"; new SQLiteCommand(sSQL, oSQLiteConnection).ExecuteNonQuery(); oFile.iID = (int)oSQLiteConnection.LastInsertRowId; } else { string sSQL = $@"UPDATE Files SET LastUpdated = '{oFile.dLastUpdated.ToString("yyyy-MM-dd HH:mm:ss")}', Deleted = {(oFile.bDeleted ? 1 : 0)}, Ignored = {(oFile.bIgnored ? 1 : 0)} WHERE ID = {oFile.iID};"; new SQLiteCommand(sSQL, oSQLiteConnection).ExecuteNonQuery(); } oSQLiteConnection.Close(); } }
public int GetRevisionCount(CVSFile oFile) { int iCount = 0; if (oFile.iID == 0) { return(iCount); } using (SQLiteConnection oSQLiteConnection = SQLConnection()) { oSQLiteConnection.Open(); using (SQLiteCommand oCmd = new SQLiteCommand($"SELECT count(id) as count FROM Commits WHERE FileID = {oFile.iID};", oSQLiteConnection)) { using (SQLiteDataReader oReader = oCmd.ExecuteReader()) { while (oReader.Read()) { iCount = int.Parse(oReader["count"].ToString()); break; } } } oSQLiteConnection.Close(); } return(iCount); }
public List <CVSFile> GetFiles(string sRootDirectory) { List <CVSFile> cFiles = new List <CVSFile>(); using (SQLiteConnection oSQLiteConnection = SQLConnection()) { oSQLiteConnection.Open(); CVSFile oFile; using (SQLiteCommand oCmd = new SQLiteCommand($"SELECT * FROM Files WHERE Path LIKE '{sRootDirectory.Replace("'", @"''")}%';", oSQLiteConnection)) { using (SQLiteDataReader oReader = oCmd.ExecuteReader()) { while (oReader.Read()) { oFile = new CVSFile { iID = int.Parse(oReader["ID"].ToString()), sName = oReader["Name"].ToString(), sPath = oReader["Path"].ToString(), sCVSPath = oReader["CVSPath"].ToString(), dLastUpdated = (DateTime)oReader["LastUpdated"], bDeleted = (int.Parse(oReader["Deleted"].ToString()) == 1) ? true : false, bIgnored = (int.Parse(oReader["Ignored"].ToString()) == 1) ? true : false }; cFiles.Add(oFile); } } } oSQLiteConnection.Close(); } return(cFiles); }
public static List <Commit> GetCommits(CVSFile oFile, List <Tag> cTags) { List <Commit> cCommits = new List <Commit>(); //Check if it's an CVS related File; those can be ignored. string sTest = oFile.sPath + "\\" + oFile.sName; if (sTest.Contains("CVS\\Repository") || sTest.Contains("CVS\\Root") || sTest.Contains("CVS\\Entries") || sTest.Contains("CVS\\Baserev")) { Console.WriteLine($"Ignored: {oFile.sPath}\\{oFile.sName}"); oFile.bIgnored = true; return(cCommits); } List <string> cLines = CVSCalls.RunCommand(oFile.sPath, $"cvs log \"{oFile.sName}\""); //If output is just 5 line, it probably means the file is not known in cvs (yet) or some other error. if (cLines.Count <= 5) { Console.WriteLine($"No Data: {oFile.sPath}\\{oFile.sName}"); return(cCommits); } int iLine = 0; List <KeyValuePair <string, string> > cRawTags = new List <KeyValuePair <string, string> >(); string sRCS = null; if (oFile.iID == 0) { if (cLines[1].Contains("RCS file:")) { sRCS = cLines[1].Replace("RCS file: ", "").Replace("/" + oFile.sName + ",v", ""); } } //Find begin of symbolic names. for (int i = iLine; i < cLines.Count; i++) { if (cLines[i].Contains("symbolic names:")) { iLine = i + 1; break; } } //Process symbolic names (aka tags). for (int i = iLine; i < cLines.Count; i++) { if (cLines[i].Contains("keyword substitution:")) { iLine = i + 1; break; } string[] aRawTag = cLines[i].Split(':'); KeyValuePair <string, string> oRawTag = new KeyValuePair <string, string>( aRawTag[0].Trim(new char[] { ' ', (char)9 }), aRawTag[1].TrimStart(' ') ); cRawTags.Add(oRawTag); } //Find begin of commits for (int i = iLine; i < cLines.Count; i++) { if (cLines[i].Contains("description:")) { iLine = i + 1; break; } } //Process commits for (int i = iLine; i < cLines.Count; i++) { Commit oCommit = new Commit(); Revision oRevision = new Revision(); oRevision.sRevision = cLines[i + 1].Replace("revision ", ""); Match oMatch; oMatch = new Regex("date: (.*?);").Match(cLines[i + 2]); oCommit.dDate = GlobalFunctions.ParseDateTime(oMatch.Groups[1].ToString()); oCommit.sAuthor = new Regex("author: (.*?);").Match(cLines[i + 2]).Groups[1].ToString(); oRevision.sState = new Regex("state: (.*?);").Match(cLines[i + 2]).Groups[1].ToString(); oRevision.sLinesChanged = new Regex("lines: (.*)").Match(cLines[i + 2]).Groups[1].ToString(); int iDescriptionStart = 3; if (cLines[i + 3].Contains("branches:")) { iDescriptionStart = 4; } oCommit.sDescription = cLines[i + iDescriptionStart]; //Collect additional description lines for (int j = i + iDescriptionStart + 1; j < cLines.Count; j++) { if (cLines[j] == "----------------------------" || cLines[j] == "=============================================================================") { i = j - 1; break; } else { oCommit.sDescription += Environment.NewLine + cLines[j]; } } oCommit.sDescription = oCommit.sDescription.Trim(); //Tags foreach (KeyValuePair <string, string> oRawTag in cRawTags) { if (oRawTag.Value == oRevision.sRevision) { bool bFound = false; foreach (Tag oTag in cTags) { if (oTag.sLabel == oRawTag.Key) { bFound = true; oRevision.cTags.Add(oTag); break; } } if (!bFound) { Tag oNewTag = new Tag { iID = 0, sLabel = oRawTag.Key }; oRevision.cTags.Add(oNewTag); cTags.Add(oNewTag); } } } //HASH using (SHA1Managed sha1 = new SHA1Managed()) { byte[] aHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(oCommit.sAuthor + oCommit.dDate.ToString() + oCommit.sDescription)); StringBuilder oSB = new StringBuilder(aHash.Length * 2); foreach (byte b in aHash) { //X2 = Upper Case oSB.Append(b.ToString("X2")); } oCommit.sHASH = oSB.ToString(); } oRevision.oFile = oFile; //Check if this file was re-added to the repository. if (cCommits.Count > 0 && !oRevision.bReAdded) { if (cCommits[cCommits.Count - 1].cRevisions[0].sState != "dead" && oRevision.sState == "dead") { cCommits[cCommits.Count - 1].cRevisions[0].bReAdded = true; } } //Finally oCommit.cRevisions.Add(oRevision); cCommits.Add(oCommit); //Check if there is another commit coming or not. if (cLines.Count - 1 - i < 5) { break; } } //Set CVS Path for File Object if (oFile.iID == 0 && !string.IsNullOrWhiteSpace(sRCS)) { if (cCommits[0].cRevisions[0].sState == "dead") { sRCS = sRCS.Replace("/Attic", ""); } string[] aSplitTempRCS = sRCS.Split('/'); List <string> cSplitRCS = new List <string>(); foreach (string sPart in aSplitTempRCS) { if (!string.IsNullOrWhiteSpace(sPart)) { string[] aSplitTemp2RCS = sPart.Split('\\'); foreach (string sPart2 in aSplitTemp2RCS) { if (!string.IsNullOrWhiteSpace(sPart2)) { cSplitRCS.Add(sPart2); } } } } List <string> cSplitFile = new List <string>(oFile.sPath.Split('\\')); int iCount = 0; if (cSplitRCS.Count < cSplitFile.Count) { iCount = cSplitRCS.Count; } else { iCount = cSplitFile.Count; } int iRCSIndex = cSplitRCS.Count - 1; int iFileIndex = cSplitFile.Count - 1; List <string> cMatches = new List <string>(); for (int g = iCount - 1; g >= 0; g--) { if (cSplitRCS[iRCSIndex] == cSplitFile[iFileIndex--]) { cMatches.Add(cSplitRCS[iRCSIndex--]); } else { break; } } for (int g = cMatches.Count - 1; g >= 0; g--) { oFile.sCVSPath += cMatches[g] + ((g != 0) ? "/" : ""); } } return(cCommits); }