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();
}
}
}