void _TextChanged() { string name = tName.Text; var a = new List <(string name, string code)>(); int nWild = 0; for (int i = 0; i < name.Length; i++) { switch (name[i]) { case '*': case '?': nWild++; break; } } if (name.Length > 0 && (nWild == 0 || name.Length - nWild >= 2)) { string sql; if (name.Contains(' ')) { sql = $"in ('{string.Join("', '", name.RxFindAll(@"\b[A-Za-z_]\w\w+", (RXFlags)0))}')"; } else if (name.FindAny("*?") >= 0) { sql = $"GLOB '{name}'"; } else { sql = $"= '{name}'"; } try { using var stat = _db.Statement("SELECT name, code FROM api WHERE name " + sql); //perf.first(); while (stat.Step()) { a.Add((stat.GetText(0), stat.GetText(1))); } //perf.nw(); //30 ms cold, 10 ms warm. Without index. } catch (SLException ex) { Debug_.Print(ex.Message); } } string s = ""; if (a.Count != 0) { s = a[0].code; if (a.Count > 1) { s = string.Join(s.Starts("internal const") ? "\r\n" : "\r\n\r\n", a.Select(o => o.code)); } s += "\r\n"; } code.ZSetText(s); }
/// <summary> /// Creates documentation provider for assembly <i>asmPath</i>. /// Returns null if its xml file does not exist. /// Returns _DocumentationProvider if xml file is big and found or successfully created and successfully loaded database for it. /// Else returns _XmlFileDocumentationProvider. /// </summary> public static DocumentationProvider Create(string asmPath) { if (s_d.TryGetValue(asmPath, out var dp)) { return(dp); } var xmlPath = Path.ChangeExtension(asmPath, "xml"); if (!filesystem.getProperties(xmlPath, out var px)) { return(null); } if (px.Size >= 10_000) { var md5 = new Hash.MD5Context(); md5.Add(xmlPath.Lower()); var dbPath = folders.ThisAppTemp + md5.Hash.ToString() + ".db"; try { if (!filesystem.getProperties(dbPath, out var pd) || pd.LastWriteTimeUtc != px.LastWriteTimeUtc) { //Debug_.Print($"creating db: {asmPath} -> {dbPath}"); filesystem.delete(dbPath); using (var d = new sqlite(dbPath)) { using var trans = d.Transaction(); d.Execute("CREATE TABLE doc (name TEXT PRIMARY KEY, xml TEXT)"); using var statInsert = d.Statement("INSERT INTO doc VALUES (?, ?)"); var xr = XmlUtil.LoadElem(xmlPath); foreach (var e in xr.Descendants("member")) { var name = e.Attr("name"); //remove <remarks> and <example>. foreach (var v in e.Descendants("remarks").ToArray()) { v.Remove(); } foreach (var v in e.Descendants("example").ToArray()) { v.Remove(); } using var reader = e.CreateReader(); reader.MoveToContent(); var xml = reader.ReadInnerXml(); //print.it(name, xml); statInsert.BindAll(name, xml).Step(); statInsert.Reset(); } trans.Commit(); d.Execute("VACUUM"); } File.SetLastWriteTimeUtc(dbPath, px.LastWriteTimeUtc); } var db = new sqlite(dbPath, SLFlags.SQLITE_OPEN_READONLY); //never mind: we don't dispose it on process exit s_d[asmPath] = dp = new _DocumentationProvider { _db = db }; return(dp); } catch (Exception ex) { Debug_.Print(ex.ToStringWithoutStack()); } } //return XmlDocumentationProvider.CreateFromFile(xmlPath); //no, need XML with root element. return(new _XmlFileDocumentationProvider(xmlPath)); }