bingo/sqlserver/Source/MangoShadowFetch.cs (200 lines of code) (raw):

using System.IO; using System; using System.Collections.Generic; using System.Collections; using System.Text; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Globalization; namespace indigo { public class MangoShadowFetch { MangoIndexData _index_data; enum SearchType { UNDEF, EXACT, GROSS, MASS }; SearchType search_type = SearchType.UNDEF; string table_copies, where_clause; bool need_xyz = false; public int? nextAfterStorageId { get; set; } public MangoShadowFetch (MangoIndexData index_data) { _index_data = index_data; } public void prepareExact (string query, string options) { int res = BingoCore.lib.mangoSetupMatch("EXACT", query, options); if (res < 0) throw new Exception(BingoCore.lib.bingoGetError()); table_copies = ""; where_clause = ""; if (options.Contains("TAU")) { where_clause = String.Format("gross = '{0}' OR gross LIKE '{0} H%%'", BingoCore.mangoTauGetQueryGross()); } else { need_xyz = (BingoCore.lib.mangoNeedCoords() != 0); _prepareExactQueryStrings(ref table_copies, ref where_clause); } search_type = SearchType.EXACT; } public void prepareGross (string query) { search_type = SearchType.GROSS; int res = BingoCore.lib.mangoSetupMatch("GROSS", query, ""); if (res < 0) throw new Exception(BingoCore.lib.bingoGetError()); where_clause = BingoCore.mangoGrossGetConditions(); } public void prepareMass (float? min, float? max) { search_type = SearchType.MASS; StringBuilder where_text = new StringBuilder(); if (min.HasValue) where_text.AppendFormat(CultureInfo.InvariantCulture, "mass >= {0} ", min.Value); if (max.HasValue) { if (where_text.Length > 0) where_text.Append(" AND "); where_text.AppendFormat(CultureInfo.InvariantCulture, " mass <= {0} ", max.Value); } where_clause = where_text.ToString(); } public IEnumerable<FetchedData> fetch (SqlConnection conn) { ArrayList res_list = new ArrayList(); StringBuilder command_text = new StringBuilder(); command_text.Append("SELECT sh.id"); if (search_type == SearchType.EXACT) { command_text.Append(", sh.cmf"); if (need_xyz) command_text.Append(", sh.xyz"); } if (search_type == SearchType.GROSS) command_text.Append(", gross"); if (search_type == SearchType.MASS) command_text.Append(", mass"); command_text.AppendFormat(" FROM {0} sh", _index_data.shadowTable); command_text.Append(table_copies); StringBuilder final_where_clause = new StringBuilder(); if (where_clause.Length > 0) { final_where_clause.Append(" ( "); final_where_clause.Append(where_clause); final_where_clause.Append(" ) "); } if (nextAfterStorageId != null) { if (final_where_clause.Length > 0) final_where_clause.Append(" and "); final_where_clause.Append(" ("); final_where_clause.AppendFormat(" storage_id > {0} ", nextAfterStorageId.Value); final_where_clause.Append(" )"); } if (final_where_clause.Length > 0) { command_text.Append(" WHERE "); command_text.Append(final_where_clause.ToString()); } if (nextAfterStorageId.HasValue) command_text.Append(" ORDER BY storage_id"); UTF8Encoding encoding = new UTF8Encoding(); using (SqlCommand cmd = new SqlCommand(command_text.ToString(), conn)) { cmd.CommandTimeout = 3600; using (SqlDataReader reader = cmd.ExecuteReader()) { byte[] xyz = new byte[0]; while (reader.Read()) { int id = Convert.ToInt32(reader[0]); int res; if (search_type == SearchType.EXACT) { byte[] cmf = (byte[])reader[1]; if (need_xyz) xyz = (byte[])reader[2]; res = BingoCore.lib.mangoMatchTargetBinary(cmf, cmf.Length, xyz, xyz.Length); } else if (search_type == SearchType.GROSS) { byte[] gross = encoding.GetBytes((string)reader[1]); res = BingoCore.lib.mangoMatchTarget(gross, gross.Length); } else if (search_type == SearchType.MASS) res = 1; else throw new Exception("Search type is undefined"); if (res == -2) throw new Exception(BingoCore.lib.bingoGetError()); if (res == -1) throw new Exception(BingoCore.lib.bingoGetWarning()); if (res == 1) { FetchedData data = new FetchedData(id); if (search_type == SearchType.MASS) data.value = (float)reader[1]; yield return data; } } } } } void _prepareExactQueryStrings (ref string table_copies_str, ref string where_clause_str) { int hash_elements_count, hash, count; BingoCore.lib.mangoGetHash(false, -1, out hash_elements_count, out hash); StringBuilder table_copies = new StringBuilder(); for (int i = 0; i < hash_elements_count; i++) table_copies.AppendFormat(", {0} t{1}", _index_data.componentsTable, i); // Create complex WHERE clause StringBuilder where_clause = new StringBuilder(); bool where_was_added = false; if (hash_elements_count > 0) { where_was_added = true; // molecule ids must be same where_clause.Append("sh.id = t0.id and "); for (int i = 1; i < hash_elements_count; i++) where_clause.AppendFormat("t{0}.id = t{1}.id and ", i - 1, i); // query components must match target components for (int i = 0; i < hash_elements_count; i++) { BingoCore.lib.mangoGetHash(false, i, out count, out hash); where_clause.AppendFormat("t{0}.hash = {1} and ", i, hash); } // components count mast must target components count string rel; if (BingoCore.lib.mangoExactNeedComponentMatching()) rel = ">="; else rel = "="; for (int i = 0; i < hash_elements_count; i++) { if (i != 0) where_clause.Append("and "); BingoCore.lib.mangoGetHash(false, i, out count, out hash); where_clause.AppendFormat("t{0}.count {1} {2} ", i, rel, count); } } if (!BingoCore.lib.mangoExactNeedComponentMatching()) { if (where_was_added) where_clause.Append("and "); // There must be no other components in target int query_fragments_count = 0; for (int i = 0; i < hash_elements_count; i++) { BingoCore.lib.mangoGetHash(false, i, out count, out hash); query_fragments_count += count; } where_clause.AppendFormat("sh.fragments = {0}", query_fragments_count); } table_copies_str = table_copies.ToString(); where_clause_str = where_clause.ToString(); } } }