public TableDefMap ExtractTableData(List <TableMapping> tableMappingList, bool cleanOracle)
        {
            SqlConnection conn = this.SqlConnection;
            // Shared.Info("begin test");
            // Test(conn);
            // Shared.Info("Completed test");

            var tableDefMap = new TableDefMap();

            Shared.Info("getting tables schema");

            /*
             * Information Schema, GetSchema differences MSSQL from MySQL:
             * Views data fails for MSSQL
             * MSSQL does not have EXTRA for columns
             * MySQL uses ulong for character field length, MSSQL uses int16
             * MySQL uses STATISTICS for indexes
             * MSSQL does not indicate unique or not unique for indexes
             * MSSQL does not use the term "Foreign Key Collections", but "ForeignKeys"
             * MSSQL foreignkeys collection does not contain most fields
             */

            /* INFORMATION_SCHEMA is kinda crap truth be told.  For SQL Server,
             * it is just as easy to write queries for exactly what we want,
             * with the added benefit that it actually works. :)
             *
             * We'll try to stay consistent with the field names output to match
             * what information schema does, but we'll make our own queries
             */


            string queryText = "SELECT A.name AS TableName, B.name AS SchemaName "
                               + "FROM sys.tables AS A JOIN sys.schemas AS B "
                               + "ON A.schema_id = B.schema_id;";

            foreach (var row in MicrosoftSQL.DataAccess.GetRows(conn, queryText))
            {
                string tableName  = (string)row["TableName"];
                string schemaName = (string)row["SchemaName"];
                string cleanName  = NameMapping.MakeCleanTableName(tableMappingList, tableName, cleanOracle);

                TableDef tableDef = new TableDef {
                    TableName       = tableName,
                    CleanName       = cleanName,
                    SchemaName      = schemaName,
                    TableType       = "TABLE",
                    ColumnDefMap    = new Dictionary <string, ColumnDef>(),
                    IndexDefMap     = new Dictionary <string, IndexDef>(),
                    ProcedureDefMap = new Dictionary <string, ProcedureDef>(),
                    FieldDefList    = new List <FieldDef>(),
                    ForeignKeyList  = new List <string>(),
                    ArgumentName    = Char.ToLowerInvariant(tableName[0]) + tableName.Substring(1)
                };
                tableDefMap[schemaName + "." + tableName] = tableDef;

                Shared.Info("Adding table " + tableName);
            }

            queryText = "SELECT A.name AS TableName, B.name AS SchemaName "
                        + "FROM sys.views AS A JOIN sys.schemas AS B "
                        + "ON A.schema_id = B.schema_id;";

            foreach (var row in MicrosoftSQL.DataAccess.GetRows(conn, queryText))
            {
                string tableName  = (string)row["TableName"];
                string schemaName = (string)row["SchemaName"];
                string cleanName  = NameMapping.MakeCleanTableName(tableMappingList, tableName, cleanOracle);

                TableDef tableDef = new TableDef {
                    TableName       = tableName,
                    CleanName       = cleanName,
                    SchemaName      = schemaName,
                    TableType       = "VIEW",
                    ColumnDefMap    = new Dictionary <string, ColumnDef>(),
                    IndexDefMap     = new Dictionary <string, IndexDef>(),
                    ProcedureDefMap = new Dictionary <string, ProcedureDef>(),
                    FieldDefList    = new List <FieldDef>(),
                    ForeignKeyList  = new List <string>()
                };
                tableDefMap[schemaName + "." + tableName] = tableDef;

                Shared.Info("Adding view " + tableName);
            }

            queryText = @"SELECT TABLE_NAME = ct.name,
            COLUMN_NAME = c.name,
			SCHEMA_NAME = sch.name,
            CHARACTER_MAXIMUM_LENGTH = c.max_length,
            DATA_TYPE = typ.name,
            IS_NULLABLE = c.is_nullable,
            IS_IDENTITY = is_identity
            FROM sys.columns c
            INNER JOIN sys.objects ct
            ON c.object_id = ct.object_id
            INNER JOIN sys.types typ
            ON c.system_type_id = typ.system_type_id
			INNER JOIN sys.schemas sch
			ON ct.schema_id = sch.schema_id
            WHERE ct.type IN ('U', 'V')
            ORDER BY TABLE_NAME, COLUMN_NAME;";
            /*  for MySQL: queryText = "SELECT COLUMN_NAME, TABLE_NAME, CHARACTER_MAXIMUM_LENGTH, DATA_TYPE, EXTRA, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS ORDER BY TABLE_NAME ASC, ORDINAL_POSITION ASC;"; */
            foreach (var row in MicrosoftSQL.DataAccess.GetRows(conn, queryText))
            {
                string columnName = (string)row["COLUMN_NAME"];
                string tableName  = (string)row["TABLE_NAME"];
                string schemaName = (string)row["SCHEMA_NAME"];

                Shared.Info("Adding column " + columnName + " from table " + tableName);

                short?dataLength;
                if (row["CHARACTER_MAXIMUM_LENGTH"] == DBNull.Value)
                {
                    dataLength = null;
                }
                else
                {
                    dataLength = (short)row["CHARACTER_MAXIMUM_LENGTH"];
                }

                string modelName = NameMapping.MakeCleanTableName(tableMappingList, tableName, cleanOracle);
                string cleanName = NameMapping.MakeCleanColumnName(tableMappingList, tableName, modelName, columnName, cleanOracle);

                bool forceToBit = false;
                if (cleanOracle == true)
                {
                    forceToBit = IsForceToBit(tableMappingList, tableName, columnName);
                }

                /* MySQL provides IsIdentity = ((string)row["EXTRA"]).Contains("auto_increment"), */
                ColumnDef columnDef = new ColumnDef {
                    ColumnName = columnName,
                    CleanName  = cleanName,
                    ColumnType = (string)row["DATA_TYPE"],
                    DataLength = (ulong?)dataLength,
                    ForceToBit = forceToBit,
                    IsIdentity = (bool)row["IS_IDENTITY"],
                    IsNullable = (bool)row["IS_NULLABLE"]
                };
                Shared.Info(tableName);

                tableDefMap[schemaName + "." + tableName].ColumnDefMap[columnName] = columnDef;
                Shared.Info("Column " + columnName + " added.");
            }


            /* will get primary key and unique key, which is used for Read and ReadFor functions */
            /* will get indexes for use in ListFor functions */

            /* had QUOTENAME function for SCHEMA_NAME and TABLE_NAME which I removed,
             * also removed SCHEMA_NAME = OBJECT_SCHEMA_NAME(i.[object_id]), */
            queryText = @"SELECT
            TABLE_NAME = ct.name,
            SCHEMA_NAME = sch.name,
            INDEX_NAME = i.name,
            PRIMARY_KEY = i.is_primary_key,
            [UNIQUE] = i.is_unique,
            COLUMN_NAME = c.Name
            FROM
            sys.indexes AS i 
            INNER JOIN 
            sys.index_columns AS ic 
            ON i.[object_id] = ic.[object_id] 
            AND i.index_id = ic.index_id
            INNER JOIN 
            sys.columns c
            ON ic.column_id = c.column_id
            AND ic.[object_id] = c.[object_id]
            INNER JOIN sys.objects ct
            ON i.object_id = ct.object_id
			INNER JOIN sys.schemas sch
			ON ct.schema_id = sch.schema_id
            WHERE ct.type IN ('U', 'V')
            ORDER BY TABLE_NAME, INDEX_NAME, ic.index_column_id;";

            foreach (var row in MicrosoftSQL.DataAccess.GetRows(conn, queryText))
            {
                string tableName  = (string)row["TABLE_NAME"];
                string schemaName = (string)row["SCHEMA_NAME"];
                string indexName  = (string)row["INDEX_NAME"];
                string columnName = (string)row["COLUMN_NAME"];

                Shared.Info("Adding index column " + columnName + " from index " + indexName + " on table " + tableName);

                // int ordinalPosition = (int)row["ORDINAL_POSITION"];
                /* SORT_ORDER */
                Shared.Info("looking for table " + tableName);
                TableDef table = tableDefMap[schemaName + "." + tableName];

                IndexDef indexDef = null;
                if (table.IndexDefMap.TryGetValue(indexName, out indexDef) == false)
                {
                    indexDef = new IndexDef {
                        IndexName = indexName,
                        // IsPrimary = (indexName == "PRIMARY"),
                        IsPrimary = (bool)row["PRIMARY_KEY"],
                        //                      IsUnique = ((bool)row["NON_UNIQUE"]!=true),
                        IsUnique      = (bool)row["UNIQUE"],
                        ColumnDefList = new List <ColumnDef>()
                    };
                    table.IndexDefMap[indexName] = indexDef;
                }

                ColumnDef columnDef = table.ColumnDefMap[columnName];
                indexDef.ColumnDefList.Add(columnDef);
            }

            queryText = @"SELECT TABLE_NAME = ct.name,
			SCHEMA_NAME = sch.name,
            COLUMN_NAME = c.name,
            REFERENCED_TABLE_NAME = rct.name,
            REFERENCED_COLUMN_NAME = rc.name,
			REFERENCED_SCHEMA_NAME = refsch.name
            FROM sys.foreign_key_columns AS fkc
            INNER JOIN sys.columns c
            ON fkc.parent_object_id = c.object_id
            AND fkc.parent_column_id = c.column_id
            INNER JOIN sys.objects ct
            ON c.object_id = ct.object_id
            INNER JOIN sys.columns rc
            ON fkc.referenced_object_id = rc.object_id
            AND fkc.referenced_column_id = rc.column_id
            INNER JOIN sys.objects rct
            ON rc.object_id = rct.object_id
			INNER JOIN sys.schemas sch
			ON ct.schema_id = sch.schema_id
			INNER JOIN sys.schemas refsch
			ON rct.schema_id = refsch.schema_id
            WHERE ct.type IN ('U', 'V')
            ORDER BY TABLE_NAME, COLUMN_NAME;";

            foreach (var row in MicrosoftSQL.DataAccess.GetRows(conn, queryText))
            {
                TableDef  tableDef  = tableDefMap[row["SCHEMA_NAME"] + "." + row["TABLE_NAME"].ToString()];
                ColumnDef columnDef = tableDef.ColumnDefMap[row["COLUMN_NAME"].ToString()];

                columnDef.ReferencedTableDef  = tableDefMap[row["REFERENCED_SCHEMA_NAME"].ToString() + "." + row["REFERENCED_TABLE_NAME"].ToString()];
                columnDef.ReferencedColumnDef = columnDef.ReferencedTableDef.ColumnDefMap[row["REFERENCED_COLUMN_NAME"].ToString()];

                Shared.Info("Adding foreign key for " + tableDef.TableName + "." + columnDef.ColumnName + " to " + columnDef.ReferencedTableDef.TableName + "." + columnDef.ReferencedColumnDef.ColumnName);
            }

            return(tableDefMap);
        }
        public List <ProcedureDef> MakeProcedureDefList(string databaseName,
                                                        string moduleName,
                                                        Dictionary <string, TableDef> tableDefMap)
        {
            /*  var tableMap = {};
             * var functionMap = {};
             * var tableArray = [];
             *
             *
             */
            SqlConnection conn = this.SqlConnection;

            var globalProcedureDefMap = new Dictionary <string, ProcedureDef>();

            using (SqlCommand command = new SqlCommand()
            {
                CommandText = $@"SELECT sobj.name as Name,    
(SELECT count(is_selected) FROM sys.sql_dependencies AS sis WHERE sobj.object_id = sis.object_id AND is_selected = 1) AS PerformsSelectCount,
                (SELECT count(is_updated) FROM sys.sql_dependencies AS siu WHERE sobj.object_id = siu.object_id AND is_updated = 1) AS PerformsUpdateCount
                FROM sys.objects AS sobj WHERE type = 'P' AND name like '{moduleName}\_%\_%' ESCAPE '\' ORDER BY name;",
                CommandType = CommandType.Text,
                Connection = conn
            }) {
                using (var reader = command.ExecuteReader()) {
                    while (reader.Read())
                    {
                        IDataRecord procRow = reader;


                        string procedureName = (string)procRow["Name"];
                        Shared.Info("Reading procedure " + procedureName);

                        /* we also have the ability to check referenced tables if need be */

                        int secondUnderscoreIndex = procedureName.IndexOf("_", moduleName.Length + 2, StringComparison.InvariantCulture);

                        string functionalName = procedureName.Substring(moduleName.Length + 1, secondUnderscoreIndex - moduleName.Length - 1);

                        Shared.Info($"moduleName:{moduleName}, functionalName:{functionalName}, secondUnderscoreIndex:{secondUnderscoreIndex}");


                        /* that is the functional name, so we want to find by that */
                        var tableDef = tableDefMap.Values.SingleOrDefault(x => NameMapping.GetFunctionalName(x) == functionalName);

                        if (tableDef == null)
                        {
                            throw new ApplicationException("Table with functional name " + functionalName + " referenced in stored procedure " + procedureName + " was not found in table definitions.");
                        }

                        ProcedureDef procedureDef = new ProcedureDef {
                            ProcedureName   = procedureName,
                            TableDef        = tableDef,
                            ParameterDefMap = new Dictionary <string, ParameterDef>(),
                            FieldDefMap     = new Dictionary <string, FieldDef>()
                        };

                        Shared.Info($"procedure {procedureName}, select:{(int)procRow["PerformsSelectCount"]}, update:{(int)procRow["PerformsUpdateCount"]} ");

                        /* DELETE and UPDATE queries will have a value in PerformsSelectCount, so we screen by PerformsUpdateCount first */
                        if ((int)procRow["PerformsUpdateCount"] > 0)
                        {
                            procedureDef.ReadOnly    = false;
                            procedureDef.OutputsRows = false;
                        }
                        else
                        {
                            procedureDef.ReadOnly    = true;
                            procedureDef.OutputsRows = true;

                            if ((int)procRow["PerformsSelectCount"] == 0)
                            {
                                throw new ApplicationException($"Procedure {procedureName} had 0 values for select and for update dependency counts");
                            }
                        }

                        tableDef.ProcedureDefMap[procedureName] = procedureDef;
                        globalProcedureDefMap[procedureName]    = procedureDef;
                    }
                }
            }



            PopulateParameters(databaseName, moduleName, globalProcedureDefMap);



            foreach (ProcedureDef procedureDef in globalProcedureDefMap.Values)
            {
                if (procedureDef.OutputsRows)
                {
                    // Shared.Info("Collecting output fields from procedure " + procedureDef.ProcedureName);
                    // Shared.Info(procedureDef.ToJSONString());

                    /* MSSQL 2012 and beyond have result set function, which we'll use in this version */
//					PopulateFields2008(procedureDef);
                    PopulateFields2012(procedureDef);
                }
            }

            return(globalProcedureDefMap.Values.ToList <ProcedureDef>());
        }
Example #3
0
        public static List <ModelDef> CreateModelDefList(string modelNamespace,
                                                         string moduleName,
                                                         Dictionary <string, ModelDef> modelDefMap,
                                                         List <ProcedureDef> procedureDefList,
                                                         List <string> ignoreTableNameList,
                                                         List <TableMapping> tableMappingList,
                                                         bool cleanOracle)
        {
            //		List<ModelDef> modelDefList = new List<ModelDef>();

            foreach (ProcedureDef procedureDef in procedureDefList)
            {
                string procedureName = procedureDef.ProcedureName;

                int firstUnderscoreIndex  = procedureName.IndexOf('_');
                int secondUnderscoreIndex = procedureName.IndexOf('_', firstUnderscoreIndex + 1);
                // int lastUnderscoreIndex = procedureName.LastIndexOf('_');

                // string modelName = procedureName.Substring(firstUnderscoreIndex + 1, lastUnderscoreIndex - firstUnderscoreIndex - 1);
                // string functionName = procedureName.Substring(lastUnderscoreIndex + 1);
                /* This assumes that no tables have underscores in their names */
                /* TODO: probably need an table name underscore removal method elsewhere. */
                string modelName    = procedureName.Substring(firstUnderscoreIndex + 1, secondUnderscoreIndex - firstUnderscoreIndex - 1);
                string functionName = procedureName.Substring(secondUnderscoreIndex + 1);

                /* skip tables we are ignoring */
                if (ignoreTableNameList.Contains(modelName))
                {
                    continue;
                }

                ModelDef modelDef = null;
                if (modelDefMap.ContainsKey(modelName))
                {
                    modelDef = modelDefMap[modelName];
                }
                else
                {
                    Shared.Info("Adding a virtual model after table named " + modelName + " from procedure " + procedureName + " which did not have a matching model in the models collection.");
                    modelDef = new ModelDef {
                        ModelName              = modelName,
                        FieldDefMap            = new Dictionary <string, FieldDef>(),
                        FunctionDefList        = new List <FunctionDef>(),
                        Namespace              = "",
                        PropertyDefMap         = new Dictionary <string, PropertyDef>(),
                        UsesBuildListFunction  = false,
                        UsesMakeObjectFunction = false,
                        IsJustTable            = true
                    };
                    modelDefMap[modelName] = modelDef;
                }

                FunctionDef functionDef = new FunctionDef {
                    FunctionName    = functionName,
                    ProcedureDef    = procedureDef,
                    ArgumentDefList = new List <ArgumentDef>()
                };

                modelDef.FunctionDefList.Add(functionDef);

                bool isSingleRow = (functionName.StartsWith("Read"));

                if (procedureDef.OutputsRows == true)
                {
                    functionDef.OutputsList         = true;
                    modelDef.UsesMakeObjectFunction = true;
                    functionDef.ReturnTypeCode      = modelDef.ModelName;
                    functionDef.ReturnTypeNamespace = modelDef.Namespace;
                    if (isSingleRow == true)
                    {
                        functionDef.OutputsList   = false;
                        functionDef.OutputsObject = true;
                    }
                    else
                    {
                        functionDef.OutputsList        = true;
                        functionDef.OutputsObject      = false;
                        modelDef.UsesBuildListFunction = true;
                    }
                }
                else
                {
                    functionDef.OutputsList   = false;
                    functionDef.OutputsObject = false;
                }

                foreach (ParameterDef parameterDef in procedureDef.ParameterDefMap.Values)
                {
                    string typeCode = TypeConvertor.ConvertNullableSQLToCSharp(parameterDef.ParameterDataTypeCode, parameterDef.IsNullable);

                    if (parameterDef.IsOutParameter == true)
                    {
                        if (functionDef.ReturnTypeCode != null)
                        {
                            throw new ApplicationException("Stored procedure " + procedureDef.ProcedureName + " returns row data but also has an out parameter: " + parameterDef.ParameterName);
                        }
                        functionDef.ReturnTypeCode      = typeCode;
                        functionDef.ReturnTypeNamespace = null;
                    }
                    else
                    {
                        bool isNullable = false;
                        if (typeCode != "string")
                        {
                            if (parameterDef.ColumnDef != null)
                            {
                                if (parameterDef.ColumnDef.IsNullable == true)
                                {
                                    isNullable = true;
                                }
                            }
                            else
                            {
                                /* if we don't know, we are going to allow them */
                                isNullable = true;
                            }
                        }



                        ArgumentDef argumentDef = new ArgumentDef {
                            ArgumentName     = Char.ToLowerInvariant(parameterDef.ParameterName[1]) + parameterDef.ParameterName.Substring(2),
                            ArgumentTypeCode = typeCode,
                            ParameterDef     = parameterDef,
                            IsNullable       = isNullable
                        };

                        parameterDef.ArgumentDef = argumentDef;

                        string      parameterName = parameterDef.ParameterName;
                        PropertyDef propertyDef   = modelDef.GetLikelyPropertyDef(parameterDef.ParameterName.Substring(1));

                        if (propertyDef != null)
                        {
                            argumentDef.PropertyDef  = propertyDef;
                            parameterDef.PropertyDef = propertyDef;
                            // Shared.Info($"DEBUG: Found propertyDef of {propertyDef.PropertyName} for parameterName:{parameterDef.ParameterName} in function {functionName}.");

                            /* TODO: seems like there should be a better way of storing isNullable at the property level */
                            /* we can't know from the models property type if strings are nullable or not so we just always assume they are */
                            if (propertyDef.PropertyTypeCode.EndsWith("?") == true || propertyDef.PropertyTypeCode == "string")
                            {
                                argumentDef.IsNullable  = true;
                                parameterDef.IsNullable = true;
                            }
                        }
                        else
                        {
                            Shared.Info($"Warning:  Could not find a propertyDef for parameterName:{parameterDef.ParameterName} in function {functionName} of {modelName}..");
                        }

                        functionDef.ArgumentDefList.Add(argumentDef);
                    }
                }

                if (procedureDef.OutputsRows == true)
                {
                    functionDef.OutputPropertyDefList = new List <PropertyDef>();
                    foreach (FieldDef fieldDef in procedureDef.FieldDefMap.Values)
                    {
                        string fieldName = fieldDef.FieldName;

                        string convertedFieldName = NameMapping.MakeCleanColumnName(tableMappingList, fieldDef.BaseTableName, modelDef.ModelName, fieldName, cleanOracle);

                        PropertyDef propertyDef = modelDef.GetLikelyPropertyDef(convertedFieldName);

                        /* We can easily get a field that is several layers back from our root object from joins
                         * in the query.
                         * for example Book.Author.City.State.Country.CountryName, and the query returns CountryName.
                         * We need to work down through the object graph to find the model that matches the table
                         * which that field is using.
                         * It may be that in the initial procedure read when we query the first recordset, with a browse value that
                         * returns join columns, that we can use that information to traverse the model tree more
                         * directly.
                         */
                        List <PropertyDef> propertyDefChain = null;
                        if (propertyDef == null)
                        {
                            var referencedModelName = NameMapping.MakeCleanTableName(tableMappingList, fieldDef.BaseTableName, cleanOracle);

                            // Shared.Info($"DEBUG:convertedFieldName:{convertedFieldName}, fieldDef.BaseTableName={fieldDef.BaseTableName}, referencedModelName={referencedModelName}");
                            if (modelDefMap.ContainsKey(referencedModelName) == true)
                            {
                                var referencedModelDef = modelDefMap[referencedModelName];

                                var usedModelDefList = new List <ModelDef>()
                                {
                                    modelDef
                                };
                                propertyDefChain = modelDef.ScanForLikelyPropertyDef(new List <PropertyDef>(), convertedFieldName, referencedModelDef, modelDefMap.Values.ToList <ModelDef>(), usedModelDefList);
                                if (propertyDefChain != null)
                                {
                                    //Shared.Info($"DEBUG: Found propertydef chain! fieldName:{convertedFieldName} in procedure {procedureDef.ProcedureName}");
                                    //propertyDefChain.ForEach(x => {
                                    //	Shared.Info($"{x.PropertyTypeNamespace}.{x.PropertyTypeCode} {x.PropertyName}");
                                    //});
                                }
                            }
                        }

                        /* if we didn't find a propertydef nor a propertydefchain, then it belongs as part of a function-specific Result output */
                        if (propertyDef == null && propertyDefChain == null)
                        {
                            if (functionDef.UsesResult == false)
                            {
                                functionDef.UsesResult            = true;
                                functionDef.ResultPropertyDefList = new List <ResultPropertyDef>();
                            }
                            functionDef.ResultPropertyDefList.Add(new ResultPropertyDef {
                                PropertyName     = CleanPropertyName(convertedFieldName),
                                PropertyTypeCode = fieldDef.DataTypeCode,
                                FieldDef         = fieldDef
                            });
                            Shared.Info($"Warning:  Could not find a propertyDef for fieldName \"{convertedFieldName}\" in procedure \"{procedureDef.ProcedureName}\".  " +
                                        $"The base table name for this field at the SQL level was \"{fieldDef.BaseTableName}\".  " +
                                        $"The converted model name was computed as \"{NameMapping.MakeCleanTableName(tableMappingList, fieldDef.BaseTableName, cleanOracle)}\".  " +
                                        $"This field will be included as a property in a result class labeled \"{functionDef.FunctionName}Result\" created just for the output of this function.");
                        }



                        /* TODO: Commented the type check because it couldn't resolve object v. key value.  May not be necessary really.
                         * /*
                         *
                         *                                      string propertyTypeCode = TypeConvertor.ConvertNullableSQLToCSharp(fieldDef.DataTypeCode, fieldDef.IsNullable);
                         *
                         *                                      if (propertyDef.PropertyTypeCode != propertyTypeCode) {
                         *                                              throw new ApplicationException("PropertyTypeCode for " + modelDef.ModelName + "." + propertyDef.PropertyName + " found " + propertyDef.PropertyTypeCode + " but wanted " + propertyTypeCode + " based on field " + fieldDef.FieldName + " with data type " +  fieldDef.DataTypeCode + " and IsNullable=" + fieldDef.IsNullable);
                         *                                      }
                         */


                        // propertyDef.FieldDefList.Add(fieldDef);
                        fieldDef.PropertyDef      = propertyDef;
                        fieldDef.PropertyDefChain = propertyDefChain;
                        functionDef.OutputPropertyDefList.Add(propertyDef);

                        if (modelDef.FieldDefMap.ContainsKey(fieldDef.FieldName))
                        {
                            FieldDef foundFieldDef = modelDef.FieldDefMap[fieldDef.FieldName];
                            if (foundFieldDef.BaseTableName != fieldDef.BaseTableName)
                            {
                                throw new ApplicationException("A stored procedure (" + procedureDef.ProcedureName + ") based on model " + modelDef.ModelName + " returned a field pointing to a base table named " + fieldDef.BaseTableName + ", but another procedure (" + foundFieldDef.ProcedureDef.ProcedureName + " had produced a field with the same name based on table " + foundFieldDef.BaseTableName + ".  Consider using two different names for this value in the two procedures.");
                            }
                        }
                        else
                        {
                            modelDef.FieldDefMap[fieldDef.FieldName] = fieldDef;
                        }
                    }
                }
            }

            return(modelDefMap.Values.ToList <ModelDef>());
        }
 private string GetFunctionalName(TableDef tableDef)
 {
     return(NameMapping.GetFunctionalName(tableDef));
 }
Example #5
0
        public static void MakeModels(List <TableDef> tableDefList, string namespaceText, string directory, List <TableMapping> tableMappingList, bool cleanOracle)
        {
            if (directory.EndsWith(Path.DirectorySeparatorChar.ToString(), false, CultureInfo.InvariantCulture) == false)
            {
                directory += Path.DirectorySeparatorChar;
            }
            foreach (var tableDef in tableDefList.OrderBy(x => x.TableName))
            {
                /* TODO: For now we skip views, but should we? */
                if (tableDef.TableType == "TABLE")
                {
                    Shared.Info("Making model from table " + tableDef.TableName);

                    var modelName = NameMapping.MakeCleanTableName(tableMappingList, tableDef.TableName, cleanOracle);
                    Shared.Info($"\t\tusing model name {modelName}");

                    StringBuilder buildText = new StringBuilder();

                    buildText.AppendLine("namespace " + namespaceText + " {\n");
                    buildText.AppendLine("\tpublic partial class " + modelName + " {\n");
                    buildText.AppendLine();

                    bool needsSystem = false;

                    foreach (var columnDef in tableDef.ColumnDefMap.Values)
                    {
                        string columnTypeCode;
                        string columnName = columnDef.ColumnName;

                        string convertedColumnName = NameMapping.MakeCleanColumnName(tableMappingList, tableDef.TableName, modelName, columnName, cleanOracle);


                        if (columnDef.ReferencedTableDef != null)
                        {
                            if (convertedColumnName.EndsWith("Key", StringComparison.InvariantCultureIgnoreCase))
                            {
                                convertedColumnName = convertedColumnName.Substring(0, convertedColumnName.Length - 3);
                            }
                            var rawReferencedTableName = columnDef.ReferencedTableDef.TableName;
                            columnTypeCode = NameMapping.MakeCleanTableName(tableMappingList, rawReferencedTableName, cleanOracle);
                        }
                        else
                        {
                            columnTypeCode = TypeConvertor.ConvertSQLToCSharp(columnDef.ColumnType);
                            if (columnTypeCode == "DateTime")
                            {
                                needsSystem = true;
                            }
                            if (columnTypeCode.Contains("[]"))
                            {
                                needsSystem = true;
                            }
                            else
                            {
                                if (columnDef.ForceToBit == true)
                                {
                                    columnTypeCode = "bool";
                                }
                                if (columnDef.IsNullable && columnTypeCode != "string")
                                {
                                    columnTypeCode += "?";
                                }
                            }
                        }



                        buildText.AppendLine("\t\tpublic " + columnTypeCode + " " + convertedColumnName + " { get; set; }");
                    }

                    buildText.AppendLine("\t}");
                    buildText.Append("}");

                    if (needsSystem)
                    {
                        buildText.Insert(0, "using System;" + Environment.NewLine);
                    }

                    File.WriteAllText(directory + modelName + ".cs", buildText.ToString());
                }
            }

            /* TODO: consider whether we want to make collections when our tables are referenced */
        }