예제 #1
0
        private void InferTable(IList <CTable> tables, CProtoRpc rpc, CProtoMessage messageIn, CTable parentTable)
        {
            var table = new CTable(DataStoreTypes.SqlServer);

            table.Schema      = InferSchema(rpc.ProtoService);
            table.TableName   = InferTableName(messageIn);
            table.DerivedFrom = messageIn;
            //add PK, Identity
            table.Column.Add(new CColumn(table)
            {
                ColumnName = $"{table.TableName}Id", IsNullable = false, ColumnTypeRaw = "bigint", ColumnType = System.Data.DbType.Int64, IsPrimaryKey = true, IsIdentity = true
            });

            if (parentTable != null)
            {
                var fk = parentTable.Column.FirstOrDefault(c => c.IsPrimaryKey);
                if (fk != null)
                {
                    var fkColumn = new CColumn(table)
                    {
                        ColumnName    = fk.ColumnName,
                        IsNullable    = fk.IsNullable,
                        ColumnType    = fk.ColumnType,
                        ColumnTypeRaw = fk.ColumnTypeRaw,
                        IsIdentity    = false
                    };
                    fkColumn.ForeignKeyColumn.Add(fk);

                    table.Column.Add(fkColumn);
                }
            }

            foreach (var p in messageIn.ProtoField)
            {
                var parameter = p;
                if (parameter.FieldType == GrpcType.__message)
                {
                    //if the inner message is just a single scalar field, lets use that
                    var m = rpc.ProtoService.ProtoFile.ProtoMessage.FirstOrDefault(pm => pm.MessageName == parameter.MessageType);
                    if (m.ProtoField.Count == 1 && !parameter.Repeated)
                    {
                        parameter = m.ProtoField.First();
                    }
                    else if (m.ProtoField.Count > 1)
                    {
                        continue;
                    }
                    else
                    {
                        continue;
                    }
                }
                var columns = InferColumns(table, rpc, parameter);

                foreach (var col in columns)
                {
                    if (!table.ColumnExists(col))
                    {
                        table.Column.Add(col);
                    }
                }
            }


            var existingTable = tables.FirstOrDefault(t => t.TableName == table.TableName);

            if (existingTable != null)
            {
                //merge the tables
                foreach (var col in table.Column)
                {
                    if (!existingTable.ColumnExists(col))
                    {
                        existingTable.Column.Add(col);
                    }
                }
            }
            else
            {
                tables.Add(table);
            }

            //now that tables has been added, add children
            //this will attempt to make sure they are in correct order for FK constraints
            foreach (var p in messageIn.ProtoField)
            {
                if (p.FieldType == GrpcType.__message && p.Repeated)
                {
                    //if the inner message is just a single scalar field, lets use that
                    var m = rpc.ProtoService.ProtoFile.ProtoMessage.FirstOrDefault(pm =>
                                                                                   pm.MessageName == p.MessageType);

                    // if (m.ProtoField.Count > 1) //its repeated, so field count doesn't matter
                    {
                        //recurse
                        InferTable(tables, rpc, m, table);
                    }
                }
            }
        }