/// <summary> /// Get the compound id prefix associated with a metatable /// </summary> /// <param name="mt"></param> /// <returns></returns> public static string GetPrefixFromRootTable( MetaTable mt) { string prefix, suffix, table; int number; if (mt == null) { return(""); } mt = mt.Root; // move to root RootTable rti = RootTable.GetFromTableName(mt.Name); if (rti == null) { return(""); } if (Lex.Eq(rti.Prefix, "none") || Lex.Eq(rti.Prefix, "multiple")) { return(""); } else { return(rti.Prefix); } }
/// <summary> /// Return true if in table have multiple prefixes and shouldn't be mixed with other tables /// </summary> /// <param name="mt"></param> /// <returns></returns> public static bool IsMultiplePrefixTable(MetaTable mt) { if (mt == null) { return(false); } RootTable rti = RootTable.GetFromTableName(mt.Root.Name); if (rti == null) { return(false); } return(rti.HasMultiplePrefixes); }
/// <summary> /// Filter a set of keys by prefix to match just the supplied root /// </summary> /// <param name="inputKeys"></param> /// <param name="rootTable"></param> /// <returns></returns> public static List <string> FilterKeysByRoot( List <string> inputKeys, MetaTable rootTable) { if (inputKeys == null) { return(inputKeys); } RootTable rti = RootTable.GetFromTableName(rootTable.Name); if (rti == null || !rti.IsStructureTable) { return(inputKeys); // if no structure database associated with root then return keys as is } string prefix = GetPrefixFromRootTable(rootTable); int addCount = 0; foreach (string key in inputKeys) // see how many keys are associated with the current root { if ((prefix == "" && key.Length > 0 && Char.IsDigit(key[0])) || // number with no prefix (prefix != "" & key.StartsWith(prefix)) || // non-blank prefix rti.HasMultiplePrefixes) // single table that stands by itself { addCount++; } } if (addCount == inputKeys.Count) { return(inputKeys); // no change } List <string> keys = new List <string>(); // need to build subset of keys foreach (string key in inputKeys) { if ((prefix == "" && key.Length > 0 && Char.IsDigit(key[0])) || // number with no prefix (prefix != "" & key.StartsWith(prefix)) || // non-blank prefix rti.HasMultiplePrefixes) // single table that stands by itself { keys.Add(key); } } return(keys); }
/// <summary> /// Normalize from int value (fast) /// </summary> /// <param name="cid"></param> /// <param name="mt"></param> /// <returns></returns> public static string Normalize( int intCid, MetaTable mt) { RootTable rt; string fmt; if (mt == null) { return(intCid.ToString()); } if (mt.Root == LastNormalizeRootMetaTable) { // same as last time? rt = LastNormalizeRootTable; fmt = LastNormalizeFmt; } else { MetaTable mtRoot = mt.Root; rt = RootTable.GetFromTableName(mtRoot.Name); if (rt == null) { return(intCid.ToString()); } fmt = "{0," + rt.InternalNumberFormat + "}"; LastNormalizeRootMetaTable = mtRoot; LastNormalizeRootTable = rt; LastNormalizeFmt = fmt; } string cidString = String.Format(fmt, intCid); if (rt.HasSinglePrefix) { cidString = rt.Prefix + cidString; } return(cidString); }
/// <summary> /// Normalize compound number for database searching/storage /// </summary> /// <param name="cid"></param> /// <param name="mt"></param> /// <returns></returns> public static string NormalizeForDatabase( string unnormalizedCid, MetaTable mt) { RootTable rti = null; MetaTable rootMt; string cid, prefix = "", suffix = "", remainder = "", nTxt = "", fmt, nCid; bool dashBeforeNumber = false, canFormat; int number = -1; // if (cid.Contains("91341")) cid = cid; // debug // if (mt == null) mt = mt; // debug cid = NormalizeCase(unnormalizedCid, mt); if (String.IsNullOrEmpty(cid)) { return(cid); } if (cid.Contains(" ")) { cid = cid.Replace(" ", "_"); // replace any spaces with underscores } if (cid.Contains("\n")) { cid = cid.Replace("\n", ""); // remove newlines } if (cid.Contains("\r")) { cid = cid.Replace("\r", ""); // remove returns } if (mt != null && !RootTable.IsStructureDatabaseRootTable(mt.Root)) { return(cid); } if (RootTable.IsMultiplePrefixTable(mt)) { return(cid); // no formatting just return as is } if (mt != null && UserObject.IsUserDatabaseStructureTableName(mt.Root.Name)) { // user database prefix = "userdatabase"; // used to lookup format if (Lex.IsInteger(cid)) { number = Int32.Parse(cid); } else { suffix = cid; } } else // other database { if (mt != null && RootTable.GetFromTableName(mt.Root.Name) == null) { return(cid); // if not a recognized database return cid as is } AnalyzeCid(cid, mt, out prefix, out dashBeforeNumber, out number, out suffix, out remainder, out rti, out rootMt, out canFormat); if (!canFormat) { return(cid); } string mtPrefix = ""; if (mt != null) // get any prefix for metatable { mtPrefix = GetPrefixFromRootTable(mt); } if (mtPrefix.EndsWith("-") && prefix != "" && !prefix.EndsWith("-")) { // adjust to allow prefix match prefix += "-"; dashBeforeNumber = false; } if (prefix == "") // if no prefix in number then add any metatable prefix { if (mtPrefix != "") { prefix = mtPrefix; } else { prefix = "none"; } } else if (mt != null && !Lex.Eq(prefix, mtPrefix)) { return(null); // if prefix invalid for database return null } } rti = RootTable.GetFromPrefix(prefix); if (rti == null && prefix == "userdatabase") { fmt = "{0,8:00000000}"; // default format for user databases prefix = ""; } else if (rti == null || Lex.IsNullOrEmpty(rti.InternalNumberFormat)) { // unknown format fmt = "{0}"; // default format if (rti != null && !rti.PrefixIsStored) { prefix = ""; // database doesn't contain prefix } } else // use supplied format { fmt = "{0," + rti.InternalNumberFormat + "}"; if (!rti.PrefixIsStored) { prefix = ""; // database doesn't contain prefix } } if (number < 0) { nTxt = ""; } else { try { nTxt = String.Format(fmt, number); } catch (Exception ex) { nTxt = number.ToString(); } } //if (Lex.StartsWith(cid, "GGO-")) nTxt = "-" + nTxt; // hack for GeneGo database, fix later if (prefix == "none") { prefix = ""; } AddDashIfAppropriate(ref prefix, dashBeforeNumber, rti); nCid = (prefix + nTxt + suffix).ToUpper(); if (nCid.Contains(" ")) { nCid = nCid.Replace(" ", "_"); // replace any internal spaces with underscores } return(nCid); }
/// <summary> /// Convert a compound number from external to internal format /// normalizing and adding a prefix as needed. /// A false prefix is added for compound collections that don't normally include /// a prefix or contain a overlapping prefix to keep compoundIds associated /// with the proper compound collection. /// This routine handles several cases: /// 1 - If mt defined & root is not a compound table then just return key as is /// 2 - If mt defined & root is a UCDB then normalize to fixed length if numeric otherwise return as is /// 3 - If mt defined & compound table root & no prefix then get any default prefix /// 4 - If string cid value then add any prefix & return as is /// 5 - if numeric cid (stored as integer or string) then add any prefix & format numeric part /// </summary> /// <param name="cid"></param> /// <param name="mt"></param> /// <returns></returns> public static string Normalize( string unnormalizedCid, MetaTable mt) { RootTable rti = null; MetaTable rootMt; string prefix = "", suffix = "", remainder = "", nTxt = "", fmt, nCid; bool dashBeforeNumber, canFormat; int number = -1; if (mt == null) { mt = mt; // debug } string cid = NormalizeCase(unnormalizedCid, mt); if (String.IsNullOrEmpty(cid)) { return(cid); } if (cid.IndexOf(",") >= 0) // if comma in list then just use chars up to comma { cid = cid.Substring(0, cid.IndexOf(",")); } AnalyzeCid(cid, mt, out prefix, out dashBeforeNumber, out number, out suffix, out remainder, out rti, out rootMt, out canFormat); if (!canFormat) { return(cid); } //if (!CanFormat(cid, prefix //if (!String.IsNullOrEmpty(remainder)) // multiple tokens, just return as is // return cid; // (for a cid like "2." the wrong value is returned, i.e. 2. // if (Lex.Eq(prefix, "MDDR") && number == 91341) prefix = prefix; // debug if (mt != null) // know the metatable this should belong to { // note: for multi-root table search the root table may not correspond to the compoundId prefix & value if (!RootTable.IsStructureDatabaseRootTable(mt.Root)) // non structure root table? { if (mt.Root.KeyMetaColumn.IsNumeric && Lex.IsInteger(cid)) { // if numeric then default internal format is length 10 with leading zeros number = int.Parse(cid); nCid = string.Format("{0:0000000000}", number); return(nCid); } else { return(cid); // just return as is } } else if (UserObject.IsUserDatabaseStructureTableName(mt.Root.Name)) { return(NormalizeForDatabase(cid, mt)); // same as for database if user database } else // Normal case, non-userDatabase structure root table { rti = RootTable.GetFromTableName(mt.Root.Name); if (prefix == "") { prefix = GetPrefixFromRootTable(mt); } if (rti != null && rti.IsStringType && String.IsNullOrEmpty(rti.InternalNumberFormat)) { // general unformatted string, just add any required prefix & return if (!String.IsNullOrEmpty(rti.Prefix) && !Lex.StartsWith(cid, rti.Prefix)) { nCid = rti.Prefix + cid; // add prefix if needed } else { nCid = cid; // just return as is } return(nCid); } } } else // metatable not defined, try to determine from prefix { if (!String.IsNullOrEmpty(prefix)) { rti = RootTable.GetFromPrefix(prefix); } else if (Lex.IsInteger(cid)) // if integer cid then use default integer cid database { rti = RootTable.GetFromPrefix(""); } } if (rti == null || Lex.IsNullOrEmpty(rti.InternalNumberFormat)) { fmt = "{0}"; // unknown prefix } else { fmt = "{0," + rti.InternalNumberFormat + "}"; } if (prefix == "") { suffix = ""; // if no prefix, disallow suffix to avoid invalid numbers for numeric keys (possibly enhance later) } if (number < 0) { nTxt = ""; // no number } else { try { nTxt = String.Format(fmt, number); } catch (Exception ex) { nTxt = number.ToString(); } } AddDashIfAppropriate(ref prefix, dashBeforeNumber, rti); nCid = prefix + nTxt + suffix; if (nCid == "") { nCid = cid.Trim(); // if nothing then return original input } return(nCid); }