コード例 #1
0
ファイル: FileParser.cs プロジェクト: blockspacer/niveum
        private static TypeSpec TranslateTypeSpec(OS.TypeSpec t, Text Text, Dictionary <Object, TextRange> InnerPositions, Dictionary <Object, TextRange> Positions)
        {
            if (t.OnTypeRef)
            {
                var r = TypeSpec.CreateTypeRef((TypeRef)(t.TypeRef.VersionedName()));
                if (InnerPositions.ContainsKey(t))
                {
                    Positions.Add(r, InnerPositions[t]);
                }
                return(r);
            }
            else if (t.OnGenericTypeSpec && t.GenericTypeSpec.TypeSpec.OnTypeRef && t.GenericTypeSpec.TypeSpec.TypeRef.NameMatches("Optional") && t.GenericTypeSpec.ParameterValues.Count == 1)
            {
                var Parameter = t.GenericTypeSpec.ParameterValues.Single();
                var InnerType = TranslateTypeSpec(Parameter, Text, InnerPositions, Positions);
                if (InnerType.OnTypeRef)
                {
                    var r = TypeSpec.CreateOptional(InnerType.TypeRef);
                    if (InnerPositions.ContainsKey(t))
                    {
                        Positions.Add(r, InnerPositions[t]);
                    }
                    return(r);
                }
            }
            else if (t.OnGenericTypeSpec && t.GenericTypeSpec.TypeSpec.OnTypeRef && t.GenericTypeSpec.TypeSpec.TypeRef.NameMatches("List") && t.GenericTypeSpec.ParameterValues.Count == 1)
            {
                var Parameter = t.GenericTypeSpec.ParameterValues.Single();
                if (Parameter.OnTypeRef && Parameter.TypeRef.NameMatches("Byte"))
                {
                    var r = TypeSpec.CreateTypeRef((TypeRef)("Binary"));
                    if (InnerPositions.ContainsKey(t))
                    {
                        Positions.Add(r, InnerPositions[t]);
                    }
                    return(r);
                }
                else
                {
                    var InnerType = TranslateTypeSpec(Parameter, Text, InnerPositions, Positions);
                    if (InnerType.OnTypeRef)
                    {
                        var r = TypeSpec.CreateList(InnerType.TypeRef);
                        if (InnerPositions.ContainsKey(t))
                        {
                            Positions.Add(r, InnerPositions[t]);
                        }
                        return(r);
                    }
                }
            }
            var oRange    = InnerPositions.ContainsKey(t) ? InnerPositions[t] : TreeFormat.Optional <TextRange> .Empty;
            var FileRange = new FileTextRange {
                Text = Text, Range = oRange
            };

            throw new InvalidEvaluationException("InvalidTypeSpec", FileRange, t);
        }
コード例 #2
0
        //在描述中可以在[]中使用如下几个标记
        //在实体上
        //  CN:<Name>                   CollectionName
        //  PK[C]:<Columns>             PrimaryKey
        //      C                       Clustered
        //  UK[C]:<Columns>             UniqueKey
        //      C                       Clustered
        //  NK[C]:<Columns>             NonUniqueKey
        //      C                       Clustered
        //在列上
        //  I                           Identity
        //  N                           Nullable
        //  P:<Params>                  TypeParameters, 例如字符串长度[P:50]
        //在导航属性上
        //  FK:<Columns>=<Columns>      ForeignKey
        //  RFK:<Columns>=<Columns>     ReverseForeignKey
        //  FNK:<Columns>=<Columns>     ForeignNonUniqueKey 即当前键可指向多种物体,没有外键约束
        //  RFNK:<Columns>=<Columns>    ReverseForeignNonUniqueKey 即目标键可指向多种物体,没有外键约束
        //  N                           Nullable,不能和FK同时使用
        //  FK和FNK只需要目标表上的键有索引,RFK和RFNK需要当前表和目标表的键都有索引
        //
        //标记可以叠加,如[CN:Users][PKC:Id1, Id2],但FK、RFK、FNK、RFNK不能叠加
        //外键中可有多个键,例如[FK:Id1, Id2=Id1, Id2]
        //索引列上可以标注减号表示递减,比如[PKC:Id1, Id2-]
        //
        //如果不存在CN,则默认使用<EntityName>
        //如果没有声明PK,则自动寻找名称为Id或者<EntityName>Id(不区分大小写)的列为[PK],但不会将该字段记为[I]
        //如果没有一个Key有C,则默认PK有C
        //如果一个非简单类型属性(导航属性)没有标明外键或反外键,则
        //    1)如果有<Name>Id的列,且该列为简单类型,类型表的主键列数量为1,则将该字段标明为[FK:<Name>Id=<Type/ElementType>.<PrimaryKey>]
        //    2)如果类型表有一个<TableName>Id的列,且该列为简单类型,当前表的主键列数量为1,则将该字段标明为[RFK:<PrimaryKey>=<Type/ElementType>.<TableName>Id]
        //如果一个String类型的列上没有标记P,则报错

        private void FillFieldAttribute(VariableDef f, Dictionary <String, EntityDef> Entities)
        {
            var t        = f.Type;
            var IsColumn = false;

            if (t.OnTypeRef)
            {
                IsColumn = !Entities.ContainsKey((String)(t.TypeRef));
            }
            else if (t.OnOptional)
            {
                IsColumn = !Entities.ContainsKey((String)(t.Optional));
            }
            else if (t.OnList)
            {
                IsColumn = !Entities.ContainsKey((String)(t.List));
            }
            else
            {
                throw new InvalidOperationException();
            }
            FieldAttribute fa = null;

            var IsNullable = false;

            if (IsColumn)
            {
                var    IsIdentity     = false;
                String TypeParameters = null;
                foreach (var a in f.Attributes)
                {
                    if (a.Key == "I")
                    {
                        IsIdentity = true;
                    }
                    else if (a.Key == "N")
                    {
                        IsNullable = true;
                    }
                    else if (a.Key == "P")
                    {
                        TypeParameters = String.Join(", ", a.Value);
                    }
                    else
                    {
                        throw new InvalidEvaluationException(String.Format("InvalidAttribute: {0}", a.Key), Positions.ContainsKey(f.Attributes) ? Positions[f.Attributes] : TreeFormat.Optional <FileTextRange> .Empty, a);
                    }
                }

                //如果一个列上没有标记P,则自动添加[P:]
                if (TypeParameters == null)
                {
                    TypeParameters = "";
                }

                fa = FieldAttribute.CreateColumn(new ColumnAttribute {
                    IsIdentity = IsIdentity, TypeParameters = TypeParameters
                });
            }
            else
            {
                if (f.Attributes.Where(a => a.Key == "FK" || a.Key == "RFK" || a.Key == "FNK" || a.Key == "RFNK").Count() > 1)
                {
                    throw new InvalidEvaluationException(String.Format("ConflictedAttributes: {0}", f.Name), Positions.ContainsKey(f.Attributes) ? Positions[f.Attributes] : TreeFormat.Optional <FileTextRange> .Empty, f);
                }
                foreach (var a in f.Attributes)
                {
                    if (a.Key == "N")
                    {
                        IsNullable = true;
                        continue;
                    }
                    var km = GetKeyMap(String.Join(", ", a.Value));
                    if (a.Key == "FK")
                    {
                        var IsReverse = false;
                        var IsUnique  = true;
                        var ThisKey   = km.ThisKey;
                        var OtherKey  = km.OtherKey;
                        fa = FieldAttribute.CreateNavigation(new NavigationAttribute {
                            IsReverse = IsReverse, IsUnique = IsUnique, ThisKey = ThisKey, OtherKey = OtherKey
                        });
                    }
                    else if (a.Key == "RFK")
                    {
                        var IsReverse = true;
                        var IsUnique  = true;
                        var ThisKey   = km.ThisKey;
                        var OtherKey  = km.OtherKey;
                        fa = FieldAttribute.CreateNavigation(new NavigationAttribute {
                            IsReverse = IsReverse, IsUnique = IsUnique, ThisKey = ThisKey, OtherKey = OtherKey
                        });
                    }
                    else if (a.Key == "FNK")
                    {
                        var IsReverse = false;
                        var IsUnique  = false;
                        var ThisKey   = km.ThisKey;
                        var OtherKey  = km.OtherKey;
                        fa = FieldAttribute.CreateNavigation(new NavigationAttribute {
                            IsReverse = IsReverse, IsUnique = IsUnique, ThisKey = ThisKey, OtherKey = OtherKey
                        });
                    }
                    else if (a.Key == "RFNK")
                    {
                        var IsReverse = true;
                        var IsUnique  = false;
                        var ThisKey   = km.ThisKey;
                        var OtherKey  = km.OtherKey;
                        fa = FieldAttribute.CreateNavigation(new NavigationAttribute {
                            IsReverse = IsReverse, IsUnique = IsUnique, ThisKey = ThisKey, OtherKey = OtherKey
                        });
                    }
                    else
                    {
                        throw new InvalidEvaluationException(String.Format("InvalidAttribute: {0}", a.Key), Positions.ContainsKey(f.Attributes) ? Positions[f.Attributes] : TreeFormat.Optional <FileTextRange> .Empty, a);
                    }
                }
                if (fa == null)
                {
                    fa = FieldAttribute.CreateNavigation(null);
                }
            }

            if (IsNullable && !t.OnOptional)
            {
                f.Type = TypeSpec.CreateOptional(t.TypeRef);
                if (Positions.ContainsKey(t))
                {
                    Positions.Add(f.Type, Positions[t]);
                }
            }

            f.Attribute = fa;
        }