private void DoUnparseAssembly(NamedRow row) { Contract.Requires(row["in_use"] == "1", "assembly is not in use"); m_database.Update("unparsed", () => { Log.WriteLine(TraceLevel.Verbose, "ObjectModel", "unparsing {0} {1} {2}", row["name"], row["culture"], row["version"]); DoDeleteAssemblyReferences(row["assembly"]); m_database.InsertOrReplace("Assemblies", row["path"], row["name"], row["culture"], row["version"], row["write_time"], row["assembly"], "0"); }); }
private void DoParseAssembly(NamedRow row) { Contract.Requires(row["in_use"] == "0", "assembly is already in use"); string path = row["path"]; try { bool fullParse = !path.Contains("/gac/") && !path.Contains("/mscorlib.dll") && File.Exists(path + ".mdb"); // TODO: might want to optionally allow full parse of mscorlib and assemblies in the gac AssemblyDefinition assembly = AssemblyCache.Load(path, true); Log.WriteLine(TraceLevel.Info, "ObjectModel", "parsing {0} {1} {2}", row["name"], row["culture"], row["version"]); foreach (IParseAssembly parser in m_boss.GetRepeated<IParseAssembly>()) { parser.Parse(path, assembly, row["assembly"], fullParse); } m_database.Update("parsed", () => { m_database.InsertOrReplace("Assemblies", path, row["name"], row["culture"], row["version"], row["write_time"], row["assembly"], "1"); }); if (fullParse) DoQueueReferencedAssemblies(assembly, path); } catch (IOException ie) { // the file system may change as we are trying to process assemblies // so we'll ignore IO errors Log.WriteLine(TraceLevel.Info, "Errors", "error parsing '{0}':", path); Log.WriteLine(TraceLevel.Info, "Errors", ie.Message); } catch (Exception e) { Console.Error.WriteLine("error parsing '{0}':", path); Console.Error.WriteLine(e); } }
private NamedRow DoGetUsedAssembly(string name, string culture) { string sql = string.Format(@" SELECT path, name, culture, version, write_time, assembly, in_use FROM Assemblies WHERE name = '{0}' AND culture = '{1}'", name, culture); NamedRows rows = m_database.QueryNamedRows(sql); NamedRow used = new NamedRow(); foreach (NamedRow row in rows) { if (row["in_use"] == "1") { Contract.Assert(used.Arity == 0, string.Format("two assemblies named {0} {1} are both in use", name, culture)); used = row; // there shouldn't be many assemblies named name so continuing won't have much of an impact on performance (and allows us to check part of the Assemblies invariant) } } return used; }
private bool DoLhsIsNewer(NamedRow lhs, NamedRow rhs) { bool newer = false; Version lhsVersion = new Version(lhs["version"]); Version rhsVersion = new Version(rhs["version"]); if (lhsVersion > rhsVersion) { newer = true; } else if (lhsVersion == rhsVersion) { long lhsTicks = long.Parse(lhs["write_time"]); long rhsTicks = long.Parse(rhs["write_time"]); if (lhsTicks > rhsTicks) newer = true; } return newer; }
private NamedRow DoGetNewestAssembly(string name, string culture) { string sql = string.Format(@" SELECT path, name, culture, version, write_time, assembly, in_use FROM Assemblies WHERE name = '{0}' AND culture = '{1}'", name, culture); NamedRows rows = m_database.QueryNamedRows(sql); NamedRow newest = new NamedRow(); foreach (NamedRow row in rows) { if (newest.Arity == 0 || DoLhsIsNewer(row, newest)) newest = row; } Contract.Assert(newest.Arity > 0, "should have found at least one assembly named " + name); return newest; }