Exemplo n.º 1
0
        private void ImplementTableGetMaxSizeMethod(TableTypeModel tableModel)
        {
            int vtableEntryCount = tableModel.MaxIndex + 1;

            // vtable length + table length + 2 * entryCount + padding to 2-byte alignment.
            int maxVtableSize = sizeof(ushort) * (2 + vtableEntryCount) + SerializationHelpers.GetMaxPadding(sizeof(ushort));
            int maxTableSize  = tableModel.NonPaddedMaxTableInlineSize + SerializationHelpers.GetMaxPadding(tableModel.Alignment);

            List <string> statements = new List <string>();

            foreach (var kvp in tableModel.IndexToMemberMap)
            {
                int index  = kvp.Key;
                var member = kvp.Value;

                if (member.ItemTypeModel.IsFixedSize)
                {
                    // This should already be accounted for in table.NonPaddedMax size above.
                    continue;
                }

                string variableName = $"index{index}Value";
                statements.Add($"var {variableName} = item.{member.PropertyInfo.Name};");

                string statement = $"runningSum += {this.InvokeGetMaxSizeMethod(member.ItemTypeModel, variableName)};";
                string condition = $"if ({variableName} != null)";
                if (member.ItemTypeModel is VectorTypeModel vectorModel && vectorModel.IsMemoryVector)
                {
                    condition = string.Empty;
                }

                statement =
                    $@" 
                    {condition}
                    {{
                        {statement}
                    }}";

                statements.Add(statement);
            }

            string body =
                $@"
            int runningSum = {maxTableSize} + {maxVtableSize};
            {string.Join("\r\n", statements)};
            return runningSum;
";

            this.GenerateGetMaxSizeMethod(tableModel.ClrType, body);
        }
        private void ImplementTableInlineWriteMethod(TableTypeModel tableModel)
        {
            var type          = tableModel.ClrType;
            int maxIndex      = tableModel.MaxIndex;
            int maxInlineSize = tableModel.NonPaddedMaxTableInlineSize;

            // Start by asking for the worst-case number of bytes from the serializationcontext.
            string methodStart =
                $@"
                int tableStart = context.{nameof(SerializationContext.AllocateSpace)}({maxInlineSize}, sizeof(int));
                writer.{nameof(SpanWriter.WriteUOffset)}(span, originalOffset, tableStart, context);
                int currentOffset = tableStart + sizeof(int); // skip past vtable soffset_t.

                var vtable = context.{nameof(SerializationContext.VTableBuilder)};
                vtable.StartObject({maxIndex});
";

            List <string> body    = new List <string>();
            List <string> writers = new List <string>();

            // load the properties of the object into locals.
            foreach (var kvp in tableModel.IndexToMemberMap)
            {
                string prepare, write;
                if (kvp.Value.ItemTypeModel.SchemaType == FlatBufferSchemaType.Union)
                {
                    (prepare, write) = this.GetUnionSerializeBlocks(kvp.Key, kvp.Value);
                }
                else
                {
                    (prepare, write) = this.GetStandardSerializeBlocks(kvp.Key, kvp.Value);
                }

                body.Add(prepare);
                writers.Add(write);
            }

            // We probably over-allocated. Figure out by how much and back up the cursor.
            // Then we can write the vtable.
            body.Add("int tableLength = currentOffset - tableStart;");
            body.Add($"context.{nameof(SerializationContext.Offset)} -= {maxInlineSize} - tableLength;");
            body.Add($"int vtablePosition = vtable.{nameof(VTableBuilder.EndObject)}(span, writer, tableLength);");
            body.Add($"writer.{nameof(SpanWriter.WriteInt)}(span, tableStart - vtablePosition, tableStart, context);");

            body.AddRange(writers);

            // These methods are often enormous, and inlining can have a detrimental effect on perf.
            this.GenerateSerializeMethod(type, $"{methodStart} \r\n {string.Join("\r\n", body)}", inline: false);
        }
Exemplo n.º 3
0
        public void TypeModel_Vector_Indexed()
        {
            var model = RuntimeTypeModel.CreateFrom(typeof(GenericTable <IIndexedVector <string, SortedVectorKeyTable <string> > >));

            Assert.AreEqual(FlatBufferSchemaType.Table, model.SchemaType);

            TableTypeModel tableModel  = (TableTypeModel)model;
            var            firstMember = tableModel.IndexToMemberMap[0];

            Assert.IsTrue(firstMember.IsSortedVector); // sorted vector is set even though it's not explicitly declared. Indexed Vectors force it to be set.

            var vectorModel = firstMember.ItemTypeModel;

            Assert.AreEqual(FlatBufferSchemaType.Vector, vectorModel.SchemaType);
        }
Exemplo n.º 4
0
    public override void Initialize()
    {
        {
            FlatBufferStructAttribute?attribute = this.ClrType.GetCustomAttribute <FlatBufferStructAttribute>();

            FlatSharpInternal.Assert(attribute != null, "Missing attribute.");
            this.attribute = attribute !;
        }

        TableTypeModel.EnsureClassCanBeInheritedByOutsideAssembly(this.ClrType, out this.preferredConstructor);
        this.onDeserializeMethod = TableTypeModel.ValidateOnDeserializedMethod(this);

        var properties = this.ClrType
                         .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                         .Select(x => new
        {
            Property  = x,
            Attribute = x.GetCustomAttribute <FlatBufferItemAttribute>() !   // suppress check here; we filter on the next line.
        })
Exemplo n.º 5
0
        private void ImplementTableReadMethod(TableTypeModel typeModel)
        {
            // We have to implement two items: The table class and the overall "read" method.
            // Let's start with the read method.
            string className = "tableReader_" + Guid.NewGuid().ToString("n");

            this.GenerateMethodDefinition(typeModel.ClrType, $"return new {className}(memory, offset + memory.{nameof(InputBuffer.ReadUOffset)}(offset));");

            // Build up a list of property overrides.
            var propertyOverrides = new List <GeneratedProperty>();

            foreach (var item in typeModel.IndexToMemberMap)
            {
                int index = item.Key;
                var value = item.Value;

                GeneratedProperty propertyStuff;
                if (value.ItemTypeModel is UnionTypeModel)
                {
                    propertyStuff = this.CreateUnionTableGetter(value, index);
                }
                else
                {
                    propertyStuff = this.CreateStandardTableProperty(value, index);
                }

                propertyOverrides.Add(propertyStuff);
            }

            string classDefinition = this.CreateClass(
                className,
                typeModel.ClrType,
                typeModel.IndexToMemberMap.Values.Select(x => x.PropertyInfo.Name),
                propertyOverrides);

            var node = CSharpSyntaxTree.ParseText(classDefinition, ParseOptions);

            this.methodDeclarations.Add(node.GetRoot());
        }
Exemplo n.º 6
0
 public static TableType ForTableType(TableTypeModel tableType, Schema schema)
 {
     return(new TableType(tableType, schema));
 }
Exemplo n.º 7
0
 public TableType(TableTypeModel tableType, Schema schema)
 {
     _tableType = tableType;
     _schema    = schema;
 }
        private (string prepareBlock, string serializeBlock) GetStandardSerializeBlocks(int index, TableMemberModel memberModel)
        {
            string valueVariableName  = $"index{index}Value";
            string offsetVariableName = $"index{index}Offset";

            string condition = $"if ({valueVariableName} != {CSharpHelpers.GetDefaultValueToken(memberModel)})";

            if ((memberModel.ItemTypeModel is VectorTypeModel vector && vector.IsMemoryVector) || memberModel.IsKey)
            {
                // 1) Memory is a struct and can't be null, and 0-length vectors are valid.
                //    Therefore, we just need to omit the conditional check entirely.

                // 2) For sorted vector keys, we must include the value since some other
                //    libraries cannot do binary search with omitted keys.
                condition = string.Empty;
            }

            string keyCheckMethodCall = string.Empty;

            if (memberModel.IsKey)
            {
                keyCheckMethodCall = $"{nameof(SortedVectorHelpers)}.{nameof(SortedVectorHelpers.EnsureKeyNonNull)}({valueVariableName});";
            }

            string prepareBlock =
                $@"
                    var {valueVariableName} = item.{memberModel.PropertyInfo.Name};
                    int {offsetVariableName} = 0;
                    {keyCheckMethodCall}
                    {condition} 
                    {{
                            currentOffset += {CSharpHelpers.GetFullMethodName(ReflectedMethods.SerializationHelpers_GetAlignmentErrorMethod)}(currentOffset, {memberModel.ItemTypeModel.Alignment});
                            {offsetVariableName} = currentOffset;
                            vtable.{nameof(VTableBuilder.SetOffset)}({index}, currentOffset - tableStart);
                            currentOffset += {memberModel.ItemTypeModel.InlineSize};
                    }}";

            string sortInvocation = string.Empty;

            if (memberModel.IsSortedVector)
            {
                VectorTypeModel  vectorModel = (VectorTypeModel)memberModel.ItemTypeModel;
                TableTypeModel   tableModel  = (TableTypeModel)vectorModel.ItemTypeModel;
                TableMemberModel keyMember   = tableModel.IndexToMemberMap.Single(x => x.Value.PropertyInfo == tableModel.KeyProperty).Value;

                var    builtInType = BuiltInType.BuiltInTypes[keyMember.ItemTypeModel.ClrType];
                string inlineSize  = builtInType.TypeModel.SchemaType == FlatBufferSchemaType.Scalar ? builtInType.TypeModel.InlineSize.ToString() : "null";

                sortInvocation = $"{nameof(SortedVectorHelpers)}.{nameof(SortedVectorHelpers.SortVector)}(" +
                                 $"span, {offsetVariableName}, {keyMember.Index}, {inlineSize}, {CSharpHelpers.GetCompilableTypeName(builtInType.SpanComparerType)}.Instance);";
            }

            string serializeBlock =
                $@"
                    if ({offsetVariableName} != 0)
                    {{
                        {this.GetSerializeInvocation(memberModel.ItemTypeModel.ClrType, valueVariableName, offsetVariableName)}
                        {sortInvocation}
                    }}";

            return(prepareBlock, serializeBlock);
        }
Exemplo n.º 9
0
        public async Task <List <SchemaModel> > ListAsync(ConfigurationModel config, CancellationToken cancellationToken = default)
        {
            var dbSchemas = await DbContext.SchemaListAsync(cancellationToken);

            if (dbSchemas == null)
            {
                return(null);
            }

            var schemas = dbSchemas?.Select(i => new SchemaModel(i)).ToList();

            // overwrite with current config
            if (config?.Schema != null)
            {
                foreach (var schema in schemas)
                {
                    // ! Do not compare with Id. The Id is different for each SQL-Server Instance
                    var currentSchema = config.Schema.SingleOrDefault(i => i.Name == schema.Name);
                    // TODO define a global and local Property "onNewSchemaFound" (IGNORE, BUILD, WARN, PROMPT) to set the default Status
                    schema.Status = (currentSchema != null)
                        ? currentSchema.Status
                        : config.Project.DefaultSchemaStatus;
                }
            }

            // reorder schemas, ignored at top
            schemas = schemas.OrderByDescending(schema => schema.Status).ToList();

            var schemaListString = string.Join(',', schemas.Where(i => i.Status != SchemaStatusEnum.Ignore).Select(i => $"'{i.Name}'"));

            if (string.IsNullOrEmpty(schemaListString))
            {
                _reportService.Warn("No schemas found or all schemas ignored!");
                return(schemas);
            }

            var storedProcedures = await DbContext.StoredProcedureListAsync(schemaListString, cancellationToken);

            var tableTypes = await DbContext.TableTypeListAsync(schemaListString, cancellationToken);

            foreach (var schema in schemas)
            {
                schema.StoredProcedures = storedProcedures.Where(i => i.SchemaName.Equals(schema.Name))?.Select(i => new StoredProcedureModel(i))?.ToList();

                if (schema.StoredProcedures == null)
                {
                    continue;
                }

                foreach (var storedProcedure in schema.StoredProcedures)
                {
                    var inputs = await DbContext.StoredProcedureInputListAsync(storedProcedure.SchemaName, storedProcedure.Name, cancellationToken);

                    storedProcedure.Input = inputs.Select(i => new StoredProcedureInputModel(i)).ToList();

                    var output = await DbContext.StoredProcedureOutputListAsync(storedProcedure.SchemaName, storedProcedure.Name, cancellationToken);

                    storedProcedure.Output = output.Select(i => new StoredProcedureOutputModel(i)).ToList();
                }

                var tableTypeModels = new List <TableTypeModel>();
                foreach (var tableType in tableTypes.Where(i => i.SchemaName.Equals(schema.Name)))
                {
                    var columns = await DbContext.TableTypeColumnListAsync(tableType.UserTypeId ?? -1, cancellationToken);

                    var tableTypeModel = new TableTypeModel(tableType, columns);
                    tableTypeModels.Add(tableTypeModel);
                }

                schema.TableTypes = tableTypeModels;
            }

            return(schemas);
        }