diff --git a/GsaGH/Components/1_Properties/CreateProfile.cs b/GsaGH/Components/1_Properties/CreateProfile.cs index 9f54ad6c4..6cc2f5c42 100644 --- a/GsaGH/Components/1_Properties/CreateProfile.cs +++ b/GsaGH/Components/1_Properties/CreateProfile.cs @@ -20,10 +20,10 @@ namespace GsaGH.Components { - /// - /// Component to create AdSec profile - /// - public class CreateProfile : GH_OasysDropDownComponent + /// + /// Component to create AdSec profile + /// + public class CreateProfile : GH_OasysDropDownComponent { #region Name and Ribbon Layout // This region handles how the component in displayed on the ribbon including name, exposure level and icon @@ -32,6 +32,7 @@ public class CreateProfile : GH_OasysDropDownComponent public override OasysPluginInfo PluginInfo => GsaGH.PluginInfo.Instance; protected override System.Drawing.Bitmap Icon => Properties.Resources.CreateProfile; + public CreateProfile() : base("Create Profile", "Profile", "Create Profile text-string for a GSA Section", CategoryName.Name(), @@ -881,19 +882,19 @@ private void Mode2Clicked() // for catalogue selection // Catalogues - private readonly Tuple, List> _cataloguedata = SqlReader.GetCataloguesDataFromSQLite(Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3")); + private readonly Tuple, List> _cataloguedata = SqlReader.Instance.GetCataloguesDataFromSQLite(Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3")); private List _catalogueNumbers = new List(); // internal db catalogue numbers private List _catalogueNames = new List(); // list of displayed catalogues bool _inclSS; // Types - private Tuple, List> _typedata = SqlReader.GetTypesDataFromSQLite(-1, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), false); + private Tuple, List> _typedata = SqlReader.Instance.GetTypesDataFromSQLite(-1, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), false); private List _typeNumbers = new List(); // internal db type numbers private List _typeNames = new List(); // list of displayed types // Sections // list of displayed sections - private List _sectionList = SqlReader.GetSectionsDataFromSQLite(new List { -1 }, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), false); + private List _sectionList = SqlReader.Instance.GetSectionsDataFromSQLite(new List { -1 }, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), false); private List _filteredlist = new List(); int _catalogueIndex = -1; //-1 is all int _typeIndex = -1; @@ -960,12 +961,12 @@ public override void SetSelected(int i, int j) // set types to all _typeIndex = -1; // update typelist with all catalogues - _typedata = SqlReader.GetTypesDataFromSQLite(_catalogueIndex, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); + _typedata = this.GetTypesDataFromSQLite(_catalogueIndex, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); _typeNames = _typedata.Item1; _typeNumbers = _typedata.Item2; // update section list to all types - _sectionList = SqlReader.GetSectionsDataFromSQLite(_typeNumbers, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); + _sectionList = SqlReader.Instance.GetSectionsDataFromSQLite(_typeNumbers, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); // filter by search pattern _filteredlist = new List(); @@ -1021,14 +1022,14 @@ public override void SetSelected(int i, int j) SelectedItems[1] = _catalogueNames[j]; // update typelist with selected input catalogue - _typedata = SqlReader.GetTypesDataFromSQLite(_catalogueIndex, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); + _typedata = SqlReader.Instance.GetTypesDataFromSQLite(_catalogueIndex, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); _typeNames = _typedata.Item1; _typeNumbers = _typedata.Item2; // update section list from new types (all new types in catalogue) List types = _typeNumbers.ToList(); types.RemoveAt(0); // remove -1 from beginning of list - _sectionList = SqlReader.GetSectionsDataFromSQLite(types, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); + _sectionList = SqlReader.Instance.GetSectionsDataFromSQLite(types, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); // filter by search pattern _filteredlist = new List(); @@ -1086,7 +1087,7 @@ public override void SetSelected(int i, int j) // section list with selected types (only types in selected type) - _sectionList = SqlReader.GetSectionsDataFromSQLite(types, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); + _sectionList = SqlReader.Instance.GetSectionsDataFromSQLite(types, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); // filter by search pattern _filteredlist = new List(); @@ -1167,6 +1168,11 @@ public override void SetSelected(int i, int j) } } + private Tuple, List> GetTypesDataFromSQLite(int catalogueIndex, string filePath, bool inclSuperseeded) + { + return SqlReader.Instance.GetTypesDataFromSQLite2(catalogueIndex, filePath, inclSuperseeded); + } + public override void UpdateUIFromSelectedItems() { if (SelectedItems[0] == "Catalogue") @@ -1179,7 +1185,7 @@ public override void UpdateUIFromSelectedItems() _catalogueNames = _cataloguedata.Item1; _catalogueNumbers = _cataloguedata.Item2; - _typedata = SqlReader.GetTypesDataFromSQLite(_catalogueIndex, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); + _typedata = SqlReader.Instance.GetTypesDataFromSQLite(_catalogueIndex, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3"), _inclSS); _typeNames = _typedata.Item1; _typeNumbers = _typedata.Item2; diff --git a/GsaGH/Components/1_Properties/GetSectionDimensions.cs b/GsaGH/Components/1_Properties/GetSectionDimensions.cs index bcea4492e..09168eb38 100644 --- a/GsaGH/Components/1_Properties/GetSectionDimensions.cs +++ b/GsaGH/Components/1_Properties/GetSectionDimensions.cs @@ -1,22 +1,20 @@ using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; using System.Windows.Forms; using Grasshopper.Kernel; using Grasshopper.Kernel.Types; +using GsaGH.Helpers.GH; +using GsaGH.Helpers.GsaAPI; using GsaGH.Parameters; using OasysGH; using OasysGH.Components; using OasysGH.Parameters; -using OasysGH.Units.Helpers; using OasysGH.Units; -using OasysUnits.Units; +using OasysGH.Units.Helpers; using OasysUnits; -using GsaGH.Helpers.GsaAPI; -using System.Globalization; -using OasysGH.Helpers; -using System.Collections.Generic; -using System.IO; -using GsaGH.Helpers; -using GsaGH.Helpers.GH; +using OasysUnits.Units; namespace GsaGH.Components { @@ -428,7 +426,7 @@ protected override void SolveInstance(IGH_DataAccess DA) else if (profile.StartsWith("CAT")) { string prof = profile.Split(' ')[2]; - List sqlValues = SqlReader.GetCatalogueProfileValues(prof, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3")); + List sqlValues = SqlReader.Instance.GetCatalogueProfileValues(prof, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3")); unit = LengthUnit.Meter; DA.SetData(i++, new GH_UnitNumber(new Length(sqlValues[0], unit).ToUnit(this.LengthUnit))); //Depth diff --git a/GsaGH/Components/2_Geometry/SectionAlignment.cs b/GsaGH/Components/2_Geometry/SectionAlignment.cs index 07327ea32..6fc9c7fa8 100644 --- a/GsaGH/Components/2_Geometry/SectionAlignment.cs +++ b/GsaGH/Components/2_Geometry/SectionAlignment.cs @@ -348,7 +348,7 @@ protected override void SolveInstance(IGH_DataAccess DA) else if (profile.StartsWith("CAT")) { string prof = profile.Split(' ')[2]; - List sqlValues = SqlReader.GetCatalogueProfileValues(prof, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3")); + List sqlValues = SqlReader.Instance.GetCatalogueProfileValues(prof, Path.Combine(AddReferencePriority.InstallPath, "sectlib.db3")); unit = LengthUnit.Meter; depth = new Length(sqlValues[0], unit); diff --git a/GsaGH/GsaGH.csproj b/GsaGH/GsaGH.csproj index c9c4e876e..aeb4fa913 100644 --- a/GsaGH/GsaGH.csproj +++ b/GsaGH/GsaGH.csproj @@ -10,7 +10,7 @@ https://github.com/arup-group/GSA-Grasshopper README.md GSALogo128.png - 0.9.39-beta + 0.9.40-beta MIT false Official Oasys GSA Grasshopper Plugin @@ -44,11 +44,12 @@ Copyright © Oasys 1985 - 2022 all - + all compile;build + @@ -65,10 +66,6 @@ Copyright © Oasys 1985 - 2022 - - ..\..\..\..\..\..\Program Files\Oasys\GSA 10.1\System.Data.SQLite.dll - False - diff --git a/GsaGH/GsaGHInfo.cs b/GsaGH/GsaGHInfo.cs index e77ebc02e..9cc521447 100644 --- a/GsaGH/GsaGHInfo.cs +++ b/GsaGH/GsaGHInfo.cs @@ -1,16 +1,11 @@ using System; -using System.IO; using System.Collections.ObjectModel; -using Grasshopper.Kernel; -using System.Reflection; -using System.Net; using System.Diagnostics; -using GsaGH.Helpers; -using System.Threading.Tasks; -using System.Windows.Forms; +using System.IO; +using System.Reflection; +using Grasshopper.Kernel; using OasysGH; using OasysGH.Helpers; -using System.Runtime.InteropServices; namespace GsaGH { @@ -209,7 +204,7 @@ public class GsaGHInfo : GH_AssemblyInfo internal const string Company = "Oasys"; internal const string Copyright = "Copyright © Oasys 1985 - 2023"; internal const string Contact = "https://www.oasys-software.com/"; - internal const string Vers = "0.9.39"; + internal const string Vers = "0.9.40"; internal static bool isBeta = true; internal static string Disclaimer = PluginName + " is pre-release and under active development, including further testing to be undertaken. It is provided \"as-is\" and you bear the risk of using it. Future versions may contain breaking changes. Any files, results, or other types of output information created using " + PluginName + " should not be relied upon without thorough and independent checking. "; internal const string ProductName = "GSA"; diff --git a/GsaGH/Helpers/GsaAPI/SqlReader.cs b/GsaGH/Helpers/GsaAPI/SqlReader.cs index e017c9ecb..6a1d71587 100644 --- a/GsaGH/Helpers/GsaAPI/SqlReader.cs +++ b/GsaGH/Helpers/GsaAPI/SqlReader.cs @@ -1,23 +1,57 @@ using System; using System.Collections.Generic; -using System.Data.SQLite; using System.Data; +using System.Data.SQLite; using System.Globalization; +using System.IO; +using System.Reflection; namespace GsaGH.Helpers.GsaAPI { /// /// Class containing functions to interface with SQLite db files. + /// Singleton makes sure this class is executed in a separate AppDomain to avoid conflicts with different SQLite versions in main AppDomain. /// - public class SqlReader + public class SqlReader : MarshalByRefObject { + public static SqlReader Instance { get { return lazy.Value; } } + private static readonly Lazy lazy = new Lazy(() => Initialize()); + + public static SqlReader Initialize() + { + // Get the full name of the EXE assembly. + string exeAssembly = Assembly.GetCallingAssembly().FullName; + string codeBase = Assembly.GetCallingAssembly().CodeBase; + UriBuilder uri = new UriBuilder(codeBase); + string path = Uri.UnescapeDataString(uri.Path); + + // Construct and initialize settings for a second AppDomain. + AppDomainSetup ads = new AppDomainSetup(); + ads.ApplicationBase = Path.GetDirectoryName(path); + ads.DisallowBindingRedirects = false; + ads.DisallowCodeDownload = true; + ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; + + // Create the second AppDomain. + AppDomain ad = AppDomain.CreateDomain("SQLite AppDomain", null, ads); + + // Create an instance of MarshalbyRefType in the second AppDomain. + // A proxy to the object is returned. + SqlReader reader = (SqlReader)ad.CreateInstanceAndUnwrap(exeAssembly, typeof(SqlReader).FullName); + return reader; + } + + public SqlReader() + { + } + /// /// Method to set up a SQLite Connection to a specified .db3 file. /// Will return a SQLite connection to the aforementioned .db3 file database. /// /// /// - public static SQLiteConnection Connection(string filePath) + public SQLiteConnection Connection(string filePath) { return new SQLiteConnection($"URI=file:{filePath};mode=ReadOnly"); } @@ -31,8 +65,9 @@ public static SQLiteConnection Connection(string filePath) /// /// Path to SecLib.db3 /// - public static Tuple, List> GetCataloguesDataFromSQLite(string filePath) + public Tuple, List> GetCataloguesDataFromSQLite(string filePath) { + // Create empty lists to work on: List catNames = new List(); List catNumber = new List(); @@ -73,7 +108,7 @@ public static Tuple, List> GetCataloguesDataFromSQLite(string /// Path to SecLib.db3 /// True if you want to include superseeded items /// - public static Tuple, List> GetTypesDataFromSQLite(int catalogue_number, string filePath, bool inclSuperseeded = false) + public Tuple, List> GetTypesDataFromSQLite2(int catalogue_number, string filePath, bool inclSuperseeded = false) { // Create empty lists to work on: List typeNames = new List(); @@ -122,6 +157,65 @@ public static Tuple, List> GetTypesDataFromSQLite(int catalogu return new Tuple, List>(typeNames, typeNumber); } + /// + /// Get section type data from SQLite file (.db3). The method returns a tuple with: + /// Item1 = list of type name (string) + /// where first item will be "All" + /// Item2 = list of type number (int) + /// where first item will be "-1" representing All + /// + /// Catalogue number to get section types from. Input -1 in first item of the input list to get all types + /// Path to SecLib.db3 + /// True if you want to include superseeded items + /// + public Tuple, List> GetTypesDataFromSQLite(int catalogue_number, string filePath, bool inclSuperseeded = false) + { + // Create empty lists to work on: + List typeNames = new List(); + List typeNumber = new List(); + + // get Catalogue numbers if input is -1 (All catalogues) + List catNumbers = new List(); + if (catalogue_number == -1) + { + Tuple, List> catalogueData = GetCataloguesDataFromSQLite(filePath); + catNumbers = catalogueData.Item2; + catNumbers.RemoveAt(0); // remove -1 from beginning of list + } + else + catNumbers.Add(catalogue_number); + + using (var db = Connection(filePath)) + { + for (int i = 0; i < catNumbers.Count; i++) + { + int cat = catNumbers[i]; + + db.Open(); + SQLiteCommand cmd = db.CreateCommand(); + if (inclSuperseeded) + cmd.CommandText = $"Select TYPE_NAME || ' -- ' || TYPE_NUM as TYPE_NAME from Types where TYPE_CAT_NUM = {cat}"; + else + cmd.CommandText = $"Select TYPE_NAME || ' -- ' || TYPE_NUM as TYPE_NAME from Types where TYPE_CAT_NUM = {cat} and not (TYPE_SUPERSEDED = True or TYPE_SUPERSEDED = TRUE or TYPE_SUPERSEDED = 1)"; + cmd.CommandType = CommandType.Text; + SQLiteDataReader r = cmd.ExecuteReader(); + while (r.Read()) + { + // get data + string sqlData = Convert.ToString(r["TYPE_NAME"]); + + // split text string + // example: Universal Beams -- 51 + typeNames.Add(sqlData.Split(new string[] { " -- " }, StringSplitOptions.None)[0]); + typeNumber.Add(Int32.Parse(sqlData.Split(new string[] { " -- " }, StringSplitOptions.None)[1])); + } + db.Close(); + } + } + typeNames.Insert(0, "All"); + typeNumber.Insert(0, -1); + return new Tuple, List>(typeNames, typeNumber); + } /// /// Get a list of section profile strings from SQLite file (.db3). The method returns a string that includes type abbriviation as accepted by GSA. @@ -130,7 +224,7 @@ public static Tuple, List> GetTypesDataFromSQLite(int catalogu /// Path to SecLib.db3 /// True if you want to include superseeded items /// - public static List GetSectionsDataFromSQLite(List type_numbers, string filePath, bool inclSuperseeded = false) + public List GetSectionsDataFromSQLite(List type_numbers, string filePath, bool inclSuperseeded = false) { // Create empty list to work on: List section = new List(); @@ -196,11 +290,11 @@ public static List GetSectionsDataFromSQLite(List type_numbers, str /// [1]: Width /// [2]: Web THK /// [3]: Flange THK - /// [4]: Root radius + /// [4]: Root radius (only if section is not welded!) /// /// /// - public static List GetCatalogueProfileValues(string profileString, string filePath) + public List GetCatalogueProfileValues(string profileString, string filePath) { // Create empty lists to work on: List values = new List(); @@ -253,6 +347,31 @@ public static List GetCatalogueProfileValues(string profileString, strin vals = data[0].Split(new string[] { " -- " }, StringSplitOptions.None); + if (vals.Length <= 1) + { + cmd.CommandText = $"Select " + + $"SECT_DEPTH_DIAM || ' -- ' || " + + $"SECT_WIDTH || ' -- ' || " + + $"SECT_WEB_THICK || ' -- ' || " + + $"SECT_FLG_THICK || ' -- ' || " + + $"as SECT_NAME from Sect INNER JOIN Types ON Sect.SECT_TYPE_NUM = Types.TYPE_NUM where SECT_NAME = \"{profileString}\" ORDER BY SECT_DATE_ADDED"; + + data = new List(); + r = cmd.ExecuteReader(); + while (r.Read()) + { + // get data + string sqlData = Convert.ToString(r["SECT_NAME"]); + + // split text string + // example (IPE100): 0.1 -- 0.055 -- 0.0041 -- 0.0057 -- 0.007 + data.Add(sqlData); + } + } + db.Close(); + + vals = data[0].Split(new string[] { " -- " }, StringSplitOptions.None); + NumberFormatInfo noComma = CultureInfo.InvariantCulture.NumberFormat; foreach (string val in vals) diff --git a/GsaGHTests/GsaGHTests.csproj b/GsaGHTests/GsaGHTests.csproj index ed32df15b..30e3205ad 100644 --- a/GsaGHTests/GsaGHTests.csproj +++ b/GsaGHTests/GsaGHTests.csproj @@ -11,6 +11,7 @@ + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -31,10 +32,6 @@ ..\..\..\..\..\..\Program Files\Oasys\GSA 10.1\GsaAPI.dll False - - ..\..\..\..\..\..\Program Files\Oasys\GSA 10.1\System.Data.SQLite.dll - False -