using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.IO; using Sarand.Net.Standard.Base.Procs; using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Dbas.Base; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace Sarand.Net.Standard.Dbas.Proc { //======================================================================= public class SaDbProcess_ConvertDbSchema : SacsProcess { //------------------------------------------------------------------- // Configuration. public new class Config : SacsProcess.Config { public Config() { } } //------------------------------------------------------------------- // Data members. private Config config; //------------------------------------------------------------------- // Construction. public SaDbProcess_ConvertDbSchema(Config config) : base(config) { this.config = config; } protected override void Dispose(bool disposing) { if (disposing) { } base.Dispose(disposing); } //------------------------------------------------------------------- // Properties. public override string ProcessDescription { get; } = "Database Definition Convertor"; public String XmlSchemaRootElementName { get; } = "DbDfnDatabase"; // Processing. protected override bool Run() { throw new NotSupportedException(ProcessDescription + " - 'Run' not supported. Use a specific conversion method."); } //------------------------------------------------------------------- // X M L T o T a b l e s //------------------------------------------------------------------- public List ConvertXmlToTables(String xmlSchemaData) { ClearProcessError(); String fn = GetType().Name + ".ConvertXmlToTables"; Dictionary tables = new Dictionary(StringComparer.OrdinalIgnoreCase); try { // Load XML data. XDocument xmlSchema = XDocument.Parse(xmlSchemaData); // Root element. XElement rootElement = xmlSchema.Root; if (rootElement == null) throw new NotSupportedException("XML schema missing root node"); String rootElementName = rootElement.GetLocalName(); if (!rootElementName.EqualsCI(XmlSchemaRootElementName)) throw new NotSupportedException("XML schema has invalid root node. Expected: " + XmlSchemaRootElementName + ". Found: " + rootElementName); // 'Tables' element. XElement tablesElement = rootElement.GetFirstChildElement("Tables"); if (tablesElement == null) throw new NotSupportedException("XML schema missing tables node"); // Iterate tables. foreach (XElement tableElement in tablesElement.GetChildElements("DbDfnTable")) { DbDfnTable tableDfn = new DbDfnTable() { Schema = tableElement.GetChildText("Schema"), Name = tableElement.GetChildText("Name"), Remarks = tableElement.GetChildText("Remarks") }; if (tableDfn.Name.IsEmpty()) throw new NotSupportedException("XML schema contains blank table name."); if (tables.ContainsKey(tableDfn.QualifiedName)) throw new NotSupportedException("XML schema contains duplicate table: " + tableDfn.QualifiedName); tables[tableDfn.QualifiedName] = tableDfn; // Columns. XElement columnsElement = tableElement.GetFirstChildElement("Columns"); if (tablesElement == null) throw new NotSupportedException("XML schema table missing columns node: " + tableDfn.QualifiedName); // Iterate columns. foreach (XElement columnElement in columnsElement.GetChildElements("DbDfnColumn")) { DbDfnColumn columnDfn = new DbDfnColumn() { Schema = tableDfn.Schema, Table = tableDfn.Name, Pos = StringUtil.ToShort(columnElement.GetChildText("Pos")), Name = columnElement.GetChildText("Name"), DataType = EnumUtil.ParseEnum(columnElement.GetChildText("DataType"), DbColumnDataType.Unknown), DataTypeName = columnElement.GetChildText("DataTypeName"), DataTypeNative = StringUtil.ToShort(columnElement.GetChildText("DataTypeNative")), DataTypeNameNative = columnElement.GetChildText("DataTypeNameNative"), IsIdentity = StringUtil.ToBool(columnElement.GetChildText("IsIdentity")), Size = StringUtil.ToLong(columnElement.GetChildText("Size")), BufferLen = StringUtil.ToLong(columnElement.GetChildText("BufferLen")), DecimalDigits = StringUtil.ToShort(columnElement.GetChildText("DecimalDigits")), Nullable = EnumUtil.ParseEnum(columnElement.GetChildText("Nullable"), DbColumnNullable.Unknown), IsNullable = StringUtil.ToBool(columnElement.GetChildText("IsNullable")), Remarks = columnElement.GetChildText("Remarks") }; tableDfn.AddColumn(columnDfn); } // Indices. XElement IndicesElement = tableElement.GetFirstChildElement("Indices"); if (IndicesElement == null) throw new NotSupportedException("XML schema table missing indices node: " + tableDfn.QualifiedName); // Iterate indices. foreach (XElement indexElement in IndicesElement.GetChildElements("DbDfnIndex")) { DbDfnIndex indexDfn = new DbDfnIndex() { Schema = tableDfn.Schema, Table = tableDfn.Name, Name = indexElement.GetChildText("Name"), IndexType = StringUtil.ToInt(indexElement.GetChildText("IndexType")), Unique = StringUtil.ToBool(indexElement.GetChildText("Unique")), Primary = StringUtil.ToBool(indexElement.GetChildText("Primary")), Clustered = StringUtil.ToBool(indexElement.GetChildText("Clustered")), Nullable = StringUtil.ToBool(indexElement.GetChildText("Nullable")), Pages = StringUtil.ToInt(indexElement.GetChildText("Pages")), UniqueValues = StringUtil.ToInt(indexElement.GetChildText("UniqueValues")), HasColumns = StringUtil.ToBool(indexElement.GetChildText("HasColumns")), }; // Index columns. XElement IndexColumnsElement = indexElement.GetFirstChildElement("Columns"); foreach (XElement indexColumnElement in IndexColumnsElement?.GetChildElements("DbDfnIndexColumn") ?? Enumerable.Empty()) { DbDfnIndexColumn indexColumn = new DbDfnIndexColumn() { Seq = StringUtil.ToShort(indexColumnElement.GetChildText("Seq")), Name = indexColumnElement.GetChildText("Name"), Ascend = StringUtil.ToBool(indexColumnElement.GetChildText("Ascend")), }; indexDfn.AddColumn(indexColumn); } tableDfn.AddIndex(indexDfn); } } } catch (Exception exc) { SetProcessError(exc.GetErrorStateMessage()); SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc)); } return tables.Values.ToList(); } //------------------------------------------------------------------- } //======================================================================= }