示例#1
0
      private Schema erlSchemaToCRUDSchema(string name)
      {
        var erlSect = GetErlSchemaSection(name);
        if (erlSect==null) 
         throw new ErlDataAccessException(StringConsts.ERL_DS_SCHEMA_MAP_NOT_KNOWN_ERROR.Args(name));

        var defs = new List<Schema.FieldDef>();

        var keyCount = 0;
        var nodeFields = erlSect.Children.Where(c => c.IsSameName(CONFIG_FIELD_SECTION));
        foreach(var nodeField in nodeFields)
        {
          var fname   = nodeField.AttrByName(Configuration.CONFIG_NAME_ATTR).Value;
          var ftitle  = nodeField.AttrByName(CONFIG_TITLE_ATTR).Value;
          var isKey   = nodeField.AttrByName(CONFIG_KEY_ATTR).ValueAsBool();
          var required= nodeField.AttrByName(CONFIG_REQUIRED_ATTR).ValueAsBool(false);
          var type = nodeField.AttrByName(CONFIG_TYPE_ATTR).Value;
          var clrType = mapErlTypeToCLR(type);

          var strDfltValue = nodeField.AttrByName(CONFIG_DEFAULT_ATTR).ValueAsString(string.Empty);
          object dfltValue = null;
          
          if (clrType!=typeof(string))
          {
            if (strDfltValue.IsNotNullOrWhiteSpace())
            {
               if (clrType==typeof(DateTime?))
                dfltValue = ((long)strDfltValue.AsType(typeof(long), false)).FromMicrosecondsSinceUnixEpochStart();
               else
                dfltValue = strDfltValue.AsType(clrType, false);
            }
          }
          else
          {
            dfltValue = strDfltValue;
          }

          if (isKey) keyCount++;

          List<string> vList = null;
                   
          var values = nodeField.Children.Where( c => c.IsSameName(CONFIG_VALUE_SECTION));
          foreach(var vnode in values)
          {
            var code = vnode.AttrByName(CONFIG_CODE_ATTR).Value;
            var disp = vnode.AttrByName(CONFIG_DISPLAY_ATTR).Value;
            if (code.IsNullOrWhiteSpace()) continue;

            if (vList==null) vList = new List<string>();
            if (disp.IsNullOrWhiteSpace())
              vList.Add(code);
            else
              vList.Add("{0}: {1}".Args(code, disp));
          }


          var atr = new FieldAttribute(
                         targetName: m_Store.TargetName, 
                         backendName: fname,
                         backendType: type,
                         storeFlag: StoreFlag.LoadAndStore,
                         key: isKey,
                         required: required,
                         dflt: dfltValue,

                         visible:   nodeField.AttrByName(CONFIG_VISIBLE_ATTR).ValueAsBool(true),
                         maxLength: nodeField.AttrByName(CONFIG_LEN_ATTR).ValueAsInt(0),
                         description: nodeField.AttrByName(CONFIG_DESCR_ATTR).Value,
                         displayFormat: nodeField.AttrByName(CONFIG_DISPLAY_FORMAT_ATTR).Value,
                         valueList: vList==null ? null : string.Join(",", vList),//"CAR: Car Driver,SMK: Smoker, REL: Religious, CNT: Country music lover, GLD: Gold collector"
                         metadata: nodeField.ToLaconicString());

          var def = new Schema.FieldDef(fname ?? ftitle, clrType, new FieldAttribute[]{atr});
          defs.Add( def );
        }//for fields 

        var result = new Schema(name, false, defs.ToArray());

        result.ExtraData[SCHEMA_KEY_COUNT] = keyCount; 

        return result;
      }
示例#2
0
        protected virtual void EmitDeserializeField(StringBuilder source, Schema.FieldDef fdef)
        {
            var t           = fdef.Type;
            var isNullable  = t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>);
            var isValueType = t.IsValueType;
            var isArray     = t.IsArray;
            var isList      = t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List <>);
            var prop        = fdef.MemberInfo.Name;

            var tcName = t.FullNameWithExpandedGenericArgs().Replace('+', '.');

            //Specialized handling via dict
            string code;

            if (!Reader.DESER_TYPE_MAP.TryGetValue(t, out code)) //we go by the model that we have now, if what was ser does not match put it in amorphous
            {
                if (isNullable || !isValueType)
                {
                    source.AppendLine("           if (dt==DataType.Null) {{ doc.{0} = null; continue;}} ".Args(prop));
                }

                if (t.IsEnum)
                {
                    source.AppendLine("           if (dt!=DataType.Int32) break;");
                    source.AppendLine("           var ev = ({0})Reader.ReadInt32(streamer);".Args(tcName));
                    source.AppendLine("           doc.{0} = ev;".Args(prop));
                    source.AppendLine("           continue;");
                    return;
                }
                else if (typeof(TypedDoc).IsAssignableFrom(t))
                {
                    source.AppendLine("           if (dt!=DataType.Doc) break;");
                    source.AppendLine("           var vdoc = new {0}();".Args(t.FullName));
                    source.AppendLine("           if (Reader.TryReadRow(doc, vdoc, streamer, CodeGenerator.GetName(name)))");
                    source.AppendLine("             doc.{0} = vdoc;".Args(prop));
                    source.AppendLine("           continue;");
                    return;
                }
                else if (isArray)
                {
                    var et = t.GetElementType();
                    if (typeof(TypedDoc).IsAssignableFrom(et))
                    {
                        source.AppendLine("           if (dt!=DataType.Array) break;");
                        source.AppendLine("           atp = Reader.ReadDataType(streamer);");
                        source.AppendLine("           if (atp!=DataType.Doc) break;");
                        source.AppendLine("           doc.{0} = Reader.ReadRowArray<{1}>(doc, streamer, CodeGenerator.GetName(name));".Args(prop, et.FullName));
                        source.AppendLine("           continue;");
                        return;
                    }
                }
                else if (isList)
                {
                    var gat = t.GetGenericArguments()[0];
                    if (typeof(TypedDoc).IsAssignableFrom(gat))
                    {
                        source.AppendLine("           if (dt!=DataType.Array) break;");
                        source.AppendLine("           atp = Reader.ReadDataType(streamer);");
                        source.AppendLine("           if (atp!=DataType.Doc) break;");
                        source.AppendLine("           doc.{0} = Reader.ReadRowList<{1}>(doc, streamer, CodeGenerator.GetName(name));".Args(prop, gat.FullName));
                        source.AppendLine("           continue;");
                        return;
                    }
                }
            }

            if (code.IsNotNullOrWhiteSpace())
            {
                source.AppendLine(code.Args(fdef.MemberInfo.Name));
                return;
            }

            //Generate
            if (isArray)
            {
                var et = t.GetElementType();
                source.AppendLine("           if (dt==DataType.Null) doc.{0} = null;".Args(prop));
                source.AppendLine("           else if (dt!=DataType.Array) break;");
                source.AppendLine("           else");
                source.AppendLine("           {");
                source.AppendLine("              atp = Reader.ReadDataType(streamer);");
                source.AppendLine("              if (atp!=DataType.{0}) break;".Args(et.Name));
                source.AppendLine("              var len = Reader.ReadArrayLength(streamer);");
                source.AppendLine("              var arr = new {0}[len];".Args(et.FullName));
                source.AppendLine("              for(var i=0; i<len; i++) arr[i] = Reader.Read{0}(streamer);".Args(et.Name));
                source.AppendLine("              doc.{0} = arr;".Args(prop));
                source.AppendLine("           }");
                source.AppendLine("           continue;");
            }
            else if (isList)
            {
                var gat = t.GetGenericArguments()[0];
                var tn  = gat.Name;
                source.AppendLine("           if (dt==DataType.Null) doc.{0} = null;".Args(prop));
                source.AppendLine("           if (dt!=DataType.Array) break;");
                source.AppendLine("           else");
                source.AppendLine("           {");
                source.AppendLine("              atp = Reader.ReadDataType(streamer);");
                source.AppendLine("              if (atp!=DataType.{0}) break;".Args(tn));
                source.AppendLine("              var len = Reader.ReadArrayLength(streamer);");
                source.AppendLine("              var lst = new List<{0}>(len);".Args(gat.FullName));
                source.AppendLine("              for(var i=0; i<len; i++) lst.Add( Reader.Read{0}(streamer) );".Args(tn));
                source.AppendLine("              doc.{0} = lst;".Args(prop));
                source.AppendLine("           }");
                source.AppendLine("           continue;");
            }
            else if (isNullable || t == typeof(string))
            {
                var tn = fdef.NonNullableType.Name;
                source.AppendLine("           if (dt==DataType.Null) doc.{0} = null;".Args(prop));
                source.AppendLine("           else if (dt==DataType.{1}) doc.{0} = Reader.Read{1}(streamer);".Args(prop, tn));
                source.AppendLine("           else break;");
                source.AppendLine("           continue;");
            }
            else //regular
            {
                var tn = fdef.NonNullableType.Name;
                source.AppendLine("           if (dt==DataType.{1}) doc.{0} = Reader.Read{1}(streamer);".Args(prop, tn));
                source.AppendLine("           else break;");
                source.AppendLine("           continue;");
            }
        }
示例#3
0
        protected virtual JSONDataMap FieldDefToJSON(Row row,
                                                     string schema,
                                                     Schema.FieldDef fdef,
                                                     string target,
                                                     string isoLang,
                                                     ModelFieldValueListLookupFunc valueListLookup)
        {
            var result = new JSONDataMap();

            result["Name"] = fdef.Name;
            result["Type"] = MapCLRTypeToJS(fdef.NonNullableType);
            var key = fdef.AnyTargetKey;

            if (key)
            {
                result["Key"] = key;
            }


            if (fdef.NonNullableType.IsEnum)
            { //Generate default lookupdict for enum
                var names  = Enum.GetNames(fdef.NonNullableType);
                var values = new JSONDataMap(true);
                foreach (var name in names)
                {
                    values[name] = name;
                }

                result["LookupDict"] = values;
            }

            var attr = fdef[target];

            if (attr != null)
            {
                if (attr.Description != null)
                {
                    result["Description"] = OnLocalizeString(schema, "Description", attr.Description, isoLang);
                }
                var str = attr.StoreFlag == StoreFlag.OnlyStore || attr.StoreFlag == StoreFlag.LoadAndStore;
                if (!str)
                {
                    result["Stored"] = false;
                }
                if (attr.Required)
                {
                    result["Required"] = attr.Required;
                }
                if (!attr.Visible)
                {
                    result["Visible"] = attr.Visible;
                }
                if (attr.Min != null)
                {
                    result["MinValue"] = attr.Min;
                }
                if (attr.Max != null)
                {
                    result["MaxValue"] = attr.Max;
                }
                if (attr.MinLength > 0)
                {
                    result["MinSize"] = attr.MinLength;
                }
                if (attr.MaxLength > 0)
                {
                    result["Size"] = attr.MaxLength;
                }
                if (attr.Default != null)
                {
                    result["DefaultValue"] = attr.Default;
                }
                if (attr.ValueList.IsNotNullOrWhiteSpace())
                {
                    var vl = OnLocalizeString(schema, "LookupDict", attr.ValueList, isoLang);
                    result["LookupDict"] = FieldAttribute.ParseValueListString(vl);
                }
                else
                {
                    var valueList = valueListLookup != null?valueListLookup(this, row, fdef, target, isoLang)
                                        : row.GetClientFieldValueList(this, fdef, target, isoLang);

                    if (valueList == null && attr.HasValueList)
                    {
                        valueList = attr.ParseValueList();
                    }

                    if (valueList != null)
                    {
                        result["LookupDict"] = valueList;
                    }
                }

                if (attr.Kind != DataKind.Text)
                {
                    result["Kind"] = MapCLRKindToJS(attr.Kind);
                }

                if (attr.CharCase != CharCase.AsIs)
                {
                    result["Case"] = MapCLRCharCaseToJS(attr.CharCase);
                }

                if (attr.Metadata != null)
                {
                    var sect = attr.Metadata[METADATA_CONFIG_FIELD];
                    if (sect.Exists)
                    {
                        result[METADATA_CONFIG_FIELD] = sect.ToConfigurationJSONDataMap();
                    }

                    foreach (var mAt in attr.Metadata.Attributes)
                    {
                        var fn = mAt.Name;
                        if (!METADATA_FIELDS.Contains(fn))
                        {
                            continue;
                        }

                        var mv = mAt.Value;
                        if (mv.IsNullOrWhiteSpace())
                        {
                            continue;
                        }

                        if (fn == "Description" || fn == "Placeholder" || fn == "LookupDict" || fn == "Hint")
                        {
                            mv = OnLocalizeString(schema, fn, mv, isoLang);
                        }

                        result[fn] = mv;
                    }
                }
            }


            return(result);
        }
                        private Schema getSchema(Query query, MySqlDataReader reader, out Schema.FieldDef[] toLoad)
                        {
                          Schema schema;
                          if (query.ResultRowType!=null)
                            schema = Schema.GetForTypedRow(query.ResultRowType);
                          else
                            schema = GetSchemaFromReader(query.Name, m_Source, reader); 
                      
                          //determine what fields to load
                          toLoad = new Schema.FieldDef[reader.FieldCount];
                          for (int i = 0; i < reader.FieldCount; i++)
                          {
                            var name = reader.GetName(i);
                            var fdef = schema[name];
                            if (fdef==null) continue;
                            var attr =  fdef[StringConsts.MYSQL_CRUD_TARGET];
                            if (attr!=null)
                            {
                                if (attr.StoreFlag!=StoreFlag.LoadAndStore && attr.StoreFlag!=StoreFlag.OnlyLoad) continue;
                            }
                            toLoad[i] = fdef;
                          }

                          return schema;
                        }
示例#5
0
        protected virtual void EmitSerializeFieldLine(StringBuilder source, Schema.FieldDef fdef)
        {
            if (source == null)
            {
                return;
            }
            var fatr = fdef.Attrs.FirstOrDefault(a => a.IsArow);

            if (fatr == null)
            {
                return;      //do not serialize this field
            }
            var name = GetName(fatr.BackendName);

            if (name == 0)
            {
                return;   //no name specified
            }
            var isValueType = fdef.Type.IsValueType;
            var isNullable  = isValueType ? fdef.NonNullableType != fdef.Type : false;

            var propertyName  = fdef.MemberInfo.Name;
            var propertyValue = propertyName;

            if (isNullable)
            {
                propertyValue = "{0}.Value".Args(propertyValue);
            }

            source.AppendLine("      // '{0}' = {1}".Args(fatr.BackendName, name));

            if (isNullable)
            {
                source.AppendLine("      if (doc.{0}.HasValue)".Args(propertyName));
            }
            else if (!isValueType)
            {
                source.AppendLine("      if (doc.{0} != null)".Args(propertyName));
            }

            var    t = fdef.NonNullableType;
            string expr;

            if (!Writer.SER_TYPE_MAP.TryGetValue(t, out expr))
            {
                if (t.IsEnum)
                {
                    source.AppendLine("      Writer.Write(streamer, {0}, (int)doc.{1});".Args(name, propertyName));
                }
                else
                if (typeof(TypedDoc).IsAssignableFrom(t))
                {
                    source.AppendLine("      Writer.WriteRow(streamer, {0}, doc.{1});".Args(name, propertyName));
                }
                else
                if (t.IsArray && typeof(TypedDoc).IsAssignableFrom(t.GetElementType()))
                {
                    source.AppendLine("      Writer.WriteRowArray(streamer, {0}, doc.{1});".Args(name, propertyName));
                }
                else
                if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List <>) && typeof(TypedDoc).IsAssignableFrom(t.GetGenericArguments()[0]))
                {
                    source.AppendLine("      Writer.WriteRowArray(streamer, {0}, doc.{1});".Args(name, propertyName));
                }
                else
                {
                    throw new ArowException(StringConsts.AROW_MEMBER_TYPE_NOT_SUPPORTED_ERROR.Args(t.Name));
                }

                if (isNullable || !isValueType)
                {
                    source.AppendLine("      else AW.WriteNull(streamer, {0});".Args(name));
                }
                return;
            }

            if (expr.IsNullOrWhiteSpace())
            {
                expr = "doc.{0}";
            }

            source.AppendLine("      AW.Write(streamer, {0}, {1});".Args(name, expr.Args(propertyValue)));

            if (isNullable || !isValueType)
            {
                source.AppendLine("      else AW.WriteNull(streamer, {0});".Args(name));
            }
        }
示例#6
0
文件: Record.cs 项目: itadapter/nfx
        protected virtual Schema.FieldDef GetFieldDefFromJSON(JSONDataMap def)
        {
            var name = def["Name"].AsString();
              var type = MapJSToCLRType(def["Type"].AsString());
              var key = def["Key"].AsBool(false);
              var description = def["Description"].AsString(null);
              var required = def["Required"].AsBool(false);
              var visible = def["Visible"].AsBool(true);
              var minValue = def["MinValue"];
              var maxValue = def["MaxValue"];
              var minLength = def["MinSize"].AsInt(0);
              var maxLength = def["Size"].AsInt(0);
              var defaultValue = def["DefaultValue"];
              var kind = MapJSToCLRKind(def["Kind"].AsString());
              var charCase = MapJSToCLRCharCase(def["Case"].AsString());

              var stored = def["Stored"].AsNullableBool();
              var storeFlag = (stored == false) ? StoreFlag.OnlyLoad : StoreFlag.LoadAndStore;

              var lookupValues = def["LookupDict"] as JSONDataMap;

              var metadata = Configuration.NewEmptyRoot();
              foreach (var kvp in def)
              {
            if (kvp.Value == null) continue;
            metadata.AddAttributeNode(kvp.Key, kvp.Value);
              }
              var mcontent = metadata.ToLaconicString(LaconfigWritingOptions.Compact);

              var attr = lookupValues == null ?
                 new FieldAttribute(
                   targetName: TargetedAttribute.ANY_TARGET,
                   storeFlag: storeFlag,
                   key: key,
                   kind: kind,
                   required: required,
                   visible: visible,
                   dflt: defaultValue,
                   min: minValue,
                   max: maxValue,
                   minLength: minLength,
                   maxLength: maxLength,
                   charCase: charCase,
                   description: description,
                   metadata: mcontent
                   // nonUI = false,
                   // formatRegExp = null,
                   // formatDescr  = null,
                   // displayFormat = null
                   ) :
                   new FieldAttribute(
                   valueList: lookupValues,
                   targetName: TargetedAttribute.ANY_TARGET,
                   storeFlag: storeFlag,
                   key: key,
                   kind: kind,
                   required: required,
                   visible: visible,
                   dflt: defaultValue,
                   min: minValue,
                   max: maxValue,
                   minLength: minLength,
                   maxLength: maxLength,
                   charCase: charCase,
                   description: description,
                   metadata: mcontent
                   // nonUI = false,
                   // formatRegExp = null,
                   // formatDescr  = null,
                   // displayFormat = null
                   );

              var fdef = new Schema.FieldDef(name, type, attr);

              return fdef;
        }
示例#7
0
        public static Schema ErlSchemaToCRUDSchema(string name, IConfigSectionNode erlSect)
        {
            var defs = new List <Schema.FieldDef>();

            var isInsert = erlSect.AttrByName(CONFIG_INSERT_ATTR).ValueAsBool(false);
            var isUpdate = erlSect.AttrByName(CONFIG_UPDATE_ATTR).ValueAsBool(false);
            var isDelete = erlSect.AttrByName(CONFIG_DELETE_ATTR).ValueAsBool(false);
            var schDescr = erlSect.AttrByName(CONFIG_DESCR_ATTR).ValueAsString();

            var isReadonly = !(isInsert || isUpdate || isDelete);

            var keyCount   = 0;
            var nodeFields = erlSect.Children.Where(c => c.IsSameName(CONFIG_FIELD_SECTION));

            foreach (var nodeField in nodeFields)
            {
                var cfg = new LaconicConfiguration();
                cfg.CreateFromNode(nodeField);
                var node = cfg.Root;

                var fname    = node.AttrByName(Configuration.CONFIG_NAME_ATTR).Value;
                var ftitle   = node.AttrByName(CONFIG_TITLE_ATTR).Value;
                var fhint    = node.AttrByName(CONFIG_DESCR_ATTR).ValueAsString("");
                var isKey    = node.AttrByName(CONFIG_KEY_ATTR).ValueAsBool();
                var required = node.AttrByName(CONFIG_REQUIRED_ATTR).ValueAsBool(false);
                var type     = node.AttrByName(CONFIG_TYPE_ATTR).Value;
                var clrType  = mapErlTypeToCLR(type);
                var fmtdesc  = node.AttrByName(CONFIG_FORMAT_DESCR_ATTR).Value;
                var dispFmt  = node.AttrByName(CONFIG_DISPLAY_FORMAT_ATTR).Value;

                if (dispFmt != null && (dispFmt.Length < 3 || dispFmt.Substring(0, 3) != "{0:"))
                {
                    dispFmt = "{{0:{0}}}".Args(dispFmt);
                }

                node.AddAttributeNode(CONFIG_TITLE_ATTR, ftitle);

                object minV = null;
                object maxV = null;

                var sv = node.AttrByName(CONFIG_MIN_ATTR).Value;
                if (sv.IsNotNullOrWhiteSpace())
                {
                    minV = sv.AsType(clrType, true);
                }

                sv = node.AttrByName(CONFIG_MAX_ATTR).Value;
                if (sv.IsNotNullOrWhiteSpace())
                {
                    maxV = sv.AsType(clrType, true);
                }


                var    strDfltValue = node.AttrByName(CONFIG_DEFAULT_ATTR).ValueAsString(string.Empty);
                object dfltValue    = null;

                if (clrType == typeof(string))
                {
                    dfltValue = strDfltValue;
                }
                else if (strDfltValue.IsNotNullOrWhiteSpace())
                {
                    dfltValue = clrType == typeof(DateTime?)
                    ? ((long)strDfltValue.AsType(typeof(long), false)).FromMicrosecondsSinceUnixEpochStart()
                    : strDfltValue.AsType(clrType, false);
                }

                if (isKey)
                {
                    keyCount++;
                }

                List <string> vList = null;

                var values = node.Children.Where(c => c.IsSameName(CONFIG_VALUE_SECTION));
                foreach (var vnode in values)
                {
                    var code = vnode.AttrByName(CONFIG_CODE_ATTR).Value;
                    var disp = vnode.AttrByName(CONFIG_DISPLAY_ATTR).Value;
                    if (code.IsNullOrWhiteSpace())
                    {
                        continue;
                    }

                    if (vList == null)
                    {
                        vList = new List <string>();
                    }
                    if (disp.IsNullOrWhiteSpace())
                    {
                        vList.Add(code);
                    }
                    else
                    {
                        vList.Add("{0}: {1}".Args(code, disp));
                    }
                }

                var caze = CharCase.AsIs;

                var ca = node.AttrByName(CONFIG_CASE_ATTR).Value;
                if (ca.EqualsOrdIgnoreCase("upper"))
                {
                    caze = CharCase.Upper;
                }
                else
                if (ca.EqualsOrdIgnoreCase("lower"))
                {
                    caze = CharCase.Lower;
                }

                var atr = new FieldAttribute(
                    targetName:    TargetedAttribute.ANY_TARGET,
                    backendName:   fname,
                    backendType:   type,
                    storeFlag:     StoreFlag.LoadAndStore,
                    key:           isKey,
                    required:      required,
                    dflt:          dfltValue,

                    min:           minV,
                    max:           maxV,

                    charCase:      caze,

                    visible:       node.AttrByName(CONFIG_VISIBLE_ATTR).ValueAsBool(true),
                    maxLength:     node.AttrByName(CONFIG_LEN_ATTR).ValueAsInt(0),
                    description:   fmtdesc.IsNullOrEmpty() ? fhint : "{0}\nFormat: {1}".Args(fhint, fmtdesc),
                    //Parsing.Utils.ParseFieldNameToDescription(ftitle, true),
                    formatRegExp:  node.AttrByName(CONFIG_FORMAT_ATTR).Value,
                    formatDescr:   fmtdesc,
                    displayFormat: dispFmt,
                    valueList:     vList == null ? null : string.Join(",", vList),//"CAR: Car Driver,SMK: Smoker, REL: Religious, CNT: Country music lover, GLD: Gold collector"
                    metadata:      node.ToLaconicString());

                var def = new Schema.FieldDef(fname, clrType, new [] { atr });
                defs.Add(def);
            }//for fields

            var result = new Schema(name, isReadonly, defs.ToArray());

            if (schDescr.IsNotNullOrWhiteSpace())
            {
                result.ExtraData[CONFIG_DESCR_ATTR] = schDescr;
            }

            result.ExtraData[SCHEMA_KEY_COUNT] = keyCount;
            result.ExtraData[Schema.EXTRA_SUPPORTS_INSERT_ATTR] = isInsert;
            result.ExtraData[Schema.EXTRA_SUPPORTS_UPDATE_ATTR] = isUpdate;
            result.ExtraData[Schema.EXTRA_SUPPORTS_DELETE_ATTR] = isDelete;

            return(result);
        }
示例#8
0
        protected virtual (bool hasValue, Exception error) CheckValueRequired(string targetName, Schema.FieldDef fdef, FieldAttribute atr, object value, string scope)
        {
            var missing =
                (value == null) ||
                (value is string strv && strv.IsNullOrWhiteSpace()) || //string null, or whitespace are treated as missing
                (value is IRequired ireq && !ireq.CheckRequired(targetName));

            if (missing)
            {
                if (atr.Required)
                {
                    return(false, new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_REQUIRED_ERROR));
                }

                return(false, null); //no other validations are needed as field is null anyway
            }

            return(true, null);
        }
示例#9
0
 protected string GetInnerScope(Schema.FieldDef fdef, string scope) => scope.IsNullOrWhiteSpace() ? fdef.Name : scope + "." + fdef.Name;
示例#10
0
        protected virtual Schema.FieldDef GetFieldDefFromJSON(JSONDataMap def)
        {
            var name         = def["Name"].AsString();
            var type         = MapJSToCLRType(def["Type"].AsString());
            var key          = def["Key"].AsBool(false);
            var description  = def["Description"].AsString(null);
            var required     = def["Required"].AsBool(false);
            var visible      = def["Visible"].AsBool(true);
            var minValue     = def["MinValue"];
            var maxValue     = def["MaxValue"];
            var minLength    = def["MinSize"].AsInt(0);
            var maxLength    = def["Size"].AsInt(0);
            var defaultValue = def["DefaultValue"];
            var kind         = MapJSToCLRKind(def["Kind"].AsString());
            var charCase     = MapJSToCLRCharCase(def["Case"].AsString());

            var stored    = def["Stored"].AsNullableBool();
            var storeFlag = (stored == false) ? StoreFlag.OnlyLoad : StoreFlag.LoadAndStore;

            var lookupValues = def["LookupDict"] as JSONDataMap;

            var metadata = Configuration.NewEmptyRoot();

            foreach (var kvp in def)
            {
                if (kvp.Value == null)
                {
                    continue;
                }
                metadata.AddAttributeNode(kvp.Key, kvp.Value);
            }
            var mcontent = metadata.ToLaconicString(LaconfigWritingOptions.Compact);

            var attr = lookupValues == null ?
                       new FieldAttribute(
                targetName: TargetedAttribute.ANY_TARGET,
                storeFlag: storeFlag,
                key: key,
                kind: kind,
                required: required,
                visible: visible,
                dflt: defaultValue,
                min: minValue,
                max: maxValue,
                minLength: minLength,
                maxLength: maxLength,
                charCase: charCase,
                description: description,
                metadata: mcontent
                // nonUI = false,
                // formatRegExp = null,
                // formatDescr  = null,
                // displayFormat = null
                ) :
                       new FieldAttribute(
                valueList: lookupValues,
                targetName: TargetedAttribute.ANY_TARGET,
                storeFlag: storeFlag,
                key: key,
                kind: kind,
                required: required,
                visible: visible,
                dflt: defaultValue,
                min: minValue,
                max: maxValue,
                minLength: minLength,
                maxLength: maxLength,
                charCase: charCase,
                description: description,
                metadata: mcontent
                // nonUI = false,
                // formatRegExp = null,
                // formatDescr  = null,
                // displayFormat = null
                );

            var fdef = new Schema.FieldDef(name, type, attr);

            return(fdef);
        }
示例#11
0
        /// <summary>
        /// Validates document field using Schema.FieldDef settings.
        /// This method is invoked by base Validate() implementation.
        /// The method is not expected to throw exception in case of failed validation, rather return exception instance because
        ///  throwing exception really hampers validation performance when many rows need to be validated
        /// </summary>
        public virtual ValidState ValidateField(ValidState state, Schema.FieldDef fdef, string scope = null)
        {
            if (fdef == null)
            {
                throw new FieldValidationException(Schema.DisplayName,
                                                   CoreConsts.NULL_STRING,
                                                   StringConsts.ARGUMENT_ERROR + ".ValidateField(fdef=null)");
            }

            var atr = fdef[state.TargetName];

            if (atr == null)
            {
                return(state);     //not found per target
            }
            var value = GetFieldValue(fdef);

            var(hasValue, error) = CheckValueRequired(state.TargetName, fdef, atr, value, scope);
            if (error != null)
            {
                return(new ValidState(state, error));
            }
            if (!hasValue)
            {
                return(state);    //nothing else left to check
            }
            state = CheckValueIValidatable(state, fdef, atr, value, scope);
            if (state.ShouldStop)
            {
                return(state);
            }

            error = CheckValueLength(state.TargetName, fdef, atr, value, scope);
            if (error != null)
            {
                state = new ValidState(state, error);
                if (state.ShouldStop)
                {
                    return(state);
                }
            }

            error = CheckValueKind(state.TargetName, fdef, atr, value, scope);
            if (error != null)
            {
                state = new ValidState(state, error);
                if (state.ShouldStop)
                {
                    return(state);
                }
            }

            error = CheckValueMinMax(state.TargetName, fdef, atr, value, scope);
            if (error != null)
            {
                state = new ValidState(state, error);
                if (state.ShouldStop)
                {
                    return(state);
                }
            }

            error = CheckValueRegExp(state.TargetName, fdef, atr, value, scope);
            if (error != null)
            {
                state = new ValidState(state, error);
                if (state.ShouldStop)
                {
                    return(state);
                }
            }

            //this is at the end as ValueList check might induce a database call  to get a pick list (when it is not cached)
            error = CheckValueList(state.TargetName, fdef, atr, value, scope);
            if (error != null)
            {
                state = new ValidState(state, error);
                if (state.ShouldStop)
                {
                    return(state);
                }
            }

            return(state);
        }
示例#12
0
        protected virtual Exception CheckValueLength(string targetName, Schema.FieldDef fdef, FieldAttribute atr, object value, string scope)
        {
            if (atr.MinLength < 1 && atr.MaxLength < 1)
            {
                return(null);
            }

            if (value is ILengthCheck lc)
            {
                if (atr.MinLength > 0 && !lc.CheckMinLength(targetName, atr.MinLength))
                {
                    return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_MIN_LENGTH_ERROR.Args(atr.MinLength)));
                }

                if (atr.MaxLength > 0 && !lc.CheckMaxLength(targetName, atr.MaxLength))
                {
                    return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_MAX_LENGTH_ERROR.Args(atr.MaxLength)));
                }

                return(null);
            }

            var isString = value is string;
            var eobj     = value as IEnumerable;
            var ecount   = !isString && eobj != null?eobj.Cast <object>().Count() : -1;

            if (atr.MinLength > 0)
            {
                if (ecount >= 0)
                {
                    if (ecount < atr.MinLength)
                    {
                        return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_MIN_LENGTH_ERROR.Args(atr.MinLength)));
                    }
                }
                else
                {
                    if (value.ToString().Length < atr.MinLength)
                    {
                        return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_MIN_LENGTH_ERROR.Args(atr.MinLength)));
                    }
                }
            }

            if (atr.MaxLength > 0)
            {
                if (ecount >= 0)
                {
                    if (ecount > atr.MaxLength)
                    {
                        return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_MAX_LENGTH_ERROR.Args(atr.MaxLength)));
                    }
                }
                else
                {
                    if (value.ToString().Length > atr.MaxLength)
                    {
                        return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_MAX_LENGTH_ERROR.Args(atr.MaxLength)));
                    }
                }
            }

            return(null);
        }
示例#13
0
        private Schema erlSchemaToCRUDSchema(string name)
        {
            var erlSect = GetErlSchemaSection(name);

            if (erlSect == null)
            {
                throw new ErlDataAccessException(StringConsts.ERL_DS_SCHEMA_MAP_NOT_KNOWN_ERROR.Args(name));
            }

            var defs = new List <Schema.FieldDef>();

            var isInsert = erlSect.AttrByName(CONFIG_INSERT_ATTR).ValueAsBool(false);
            var isUpdate = erlSect.AttrByName(CONFIG_UPDATE_ATTR).ValueAsBool(false);
            var isDelete = erlSect.AttrByName(CONFIG_DELETE_ATTR).ValueAsBool(false);

            var isReadonly = !(isInsert || isUpdate || isDelete);


            var keyCount   = 0;
            var nodeFields = erlSect.Children.Where(c => c.IsSameName(CONFIG_FIELD_SECTION));

            foreach (var nodeField in nodeFields)
            {
                var fname    = nodeField.AttrByName(Configuration.CONFIG_NAME_ATTR).Value;
                var ftitle   = nodeField.AttrByName(CONFIG_TITLE_ATTR).Value;
                var isKey    = nodeField.AttrByName(CONFIG_KEY_ATTR).ValueAsBool();
                var required = nodeField.AttrByName(CONFIG_REQUIRED_ATTR).ValueAsBool(false);
                var type     = nodeField.AttrByName(CONFIG_TYPE_ATTR).Value;
                var clrType  = mapErlTypeToCLR(type);

                object minV = null;
                object maxV = null;

                var sv = nodeField.AttrByName(CONFIG_MIN_ATTR).Value;
                if (sv.IsNotNullOrWhiteSpace())
                {
                    minV = sv.AsType(clrType, true);
                }

                sv = nodeField.AttrByName(CONFIG_MAX_ATTR).Value;
                if (sv.IsNotNullOrWhiteSpace())
                {
                    maxV = sv.AsType(clrType, true);
                }



                var    strDfltValue = nodeField.AttrByName(CONFIG_DEFAULT_ATTR).ValueAsString(string.Empty);
                object dfltValue    = null;

                if (clrType != typeof(string))
                {
                    if (strDfltValue.IsNotNullOrWhiteSpace())
                    {
                        if (clrType == typeof(DateTime?))
                        {
                            dfltValue = ((long)strDfltValue.AsType(typeof(long), false)).FromMicrosecondsSinceUnixEpochStart();
                        }
                        else
                        {
                            dfltValue = strDfltValue.AsType(clrType, false);
                        }
                    }
                }
                else
                {
                    dfltValue = strDfltValue;
                }

                if (isKey)
                {
                    keyCount++;
                }

                List <string> vList = null;

                var values = nodeField.Children.Where(c => c.IsSameName(CONFIG_VALUE_SECTION));
                foreach (var vnode in values)
                {
                    var code = vnode.AttrByName(CONFIG_CODE_ATTR).Value;
                    var disp = vnode.AttrByName(CONFIG_DISPLAY_ATTR).Value;
                    if (code.IsNullOrWhiteSpace())
                    {
                        continue;
                    }

                    if (vList == null)
                    {
                        vList = new List <string>();
                    }
                    if (disp.IsNullOrWhiteSpace())
                    {
                        vList.Add(code);
                    }
                    else
                    {
                        vList.Add("{0}: {1}".Args(code, disp));
                    }
                }


                var caze = CharCase.AsIs;

                var ca = nodeField.AttrByName(CONFIG_CASE_ATTR).Value;
                if (ca.EqualsOrdIgnoreCase("upper"))
                {
                    caze = CharCase.Upper;
                }
                else
                if (ca.EqualsOrdIgnoreCase("lower"))
                {
                    caze = CharCase.Lower;
                }


                var atr = new FieldAttribute(
                    targetName: m_Store.TargetName,
                    backendName: fname,
                    backendType: type,
                    storeFlag: StoreFlag.LoadAndStore,
                    key: isKey,
                    required: required,
                    dflt: dfltValue,

                    min: minV,
                    max: maxV,

                    charCase: caze,

                    visible:   nodeField.AttrByName(CONFIG_VISIBLE_ATTR).ValueAsBool(true),
                    maxLength: nodeField.AttrByName(CONFIG_LEN_ATTR).ValueAsInt(0),
                    description: ftitle,
                    formatRegExp: nodeField.AttrByName(CONFIG_FORMAT_ATTR).Value,
                    formatDescr: nodeField.AttrByName(CONFIG_FORMAT_DESCR_ATTR).Value,
                    displayFormat: nodeField.AttrByName(CONFIG_DISPLAY_FORMAT_ATTR).Value,
                    valueList: vList == null ? null : string.Join(",", vList),   //"CAR: Car Driver,SMK: Smoker, REL: Religious, CNT: Country music lover, GLD: Gold collector"
                    metadata: nodeField.ToLaconicString());

                var def = new Schema.FieldDef(fname, clrType, new FieldAttribute[] { atr });
                defs.Add(def);
            }//for fields



            var result = new Schema(name, isReadonly, defs.ToArray());

            result.ExtraData[SCHEMA_KEY_COUNT] = keyCount;
            result.ExtraData[Schema.EXTRA_SUPPORTS_INSERT_ATTR] = isInsert;
            result.ExtraData[Schema.EXTRA_SUPPORTS_UPDATE_ATTR] = isUpdate;
            result.ExtraData[Schema.EXTRA_SUPPORTS_DELETE_ATTR] = isDelete;

            return(result);
        }
示例#14
0
        protected virtual (bool hasValue, Exception error) CheckValueRequired(string targetName, Schema.FieldDef fdef, FieldAttribute atr, object value)
        {
            if (value == null ||
                (value is string strv && strv.IsNullOrWhiteSpace()) ||
                (value is GDID gdid && gdid.IsZero))
            {
                if (atr.Required)
                {
                    return(false, new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_REQUIRED_ERROR));
                }

                return(false, null); //no other validations are needed as field is null anyway
            }

            return(true, null);
        }
        /// <summary>
        /// Gets CRUD schema from MySqlReader per particular QuerySource.
        /// If source is null then all columns from reader are copied.
        /// Note: this code was purposely made provider specific because other providers may treat some nuances differently
        /// </summary>
        public static Schema GetSchemaFromReader(string name, QuerySource source, MySqlDataReader reader)
        {
            var table = name;
               var fdefs = new List<Schema.FieldDef>();

               for (int i = 0; i < reader.FieldCount; i++)
               {
                    var fname = reader.GetName(i);
                    var ftype = reader.GetFieldType(i);

                    var def = new Schema.FieldDef(fname, ftype, source!=null ? ( source.HasPragma ? source.ColumnDefs[fname] : null) : null);
                    fdefs.Add( def );
               }

               if (source!=null)
                if (source.HasPragma && source.ModifyTarget.IsNotNullOrWhiteSpace()) table = source.ModifyTarget;

               if (table.IsNullOrWhiteSpace()) table = Guid.NewGuid().ToString();

               return new Schema(table, source!=null ? source.ReadOnly : true,  fdefs);
        }
示例#16
0
        private static (object value, OracleDbType?dbType) getDbFieldValue(Doc doc, Schema.FieldDef fld, FieldAttribute fattr, OracleDataStoreBase store)
        {
            var result = doc.GetFieldValue(fld);

            return(CLRValueToDB(store, result, fattr.BackendType));
        }
        /// <summary>
        /// Gets schema from reader taking Query.ResultRowType in consideration
        /// </summary>
        public static Schema GetSchemaForQuery(string target, Query query, MySqlDataReader reader, QuerySource qSource, out Schema.FieldDef[] toLoad)
        {
            Schema schema;
              var rtp = query.ResultRowType;

              if (rtp != null && typeof(TypedRow).IsAssignableFrom(rtp))
                schema = Schema.GetForTypedRow(query.ResultRowType);
              else
                schema = GetSchemaFromReader(query.Name, qSource, reader);

              //determine what fields to load
              toLoad = new Schema.FieldDef[reader.FieldCount];
              for (int i = 0; i < reader.FieldCount; i++)
              {
                var name = reader.GetName(i);
                var fdef = schema[name];

              //todo A gde GetBackendNameFor target?
                if (fdef==null) continue;
                var attr =  fdef[target];
                if (attr!=null)
                {
                  if (attr.StoreFlag!=StoreFlag.LoadAndStore && attr.StoreFlag!=StoreFlag.OnlyLoad) continue;
                }
                toLoad[i] = fdef;
              }

              return schema;
        }
示例#18
0
        protected virtual JSONDataMap FieldDefToJSON(string schema, Schema.FieldDef fdef, string target, string isoLang = null)
        {
            var result = new JSONDataMap();

            result["Name"] = fdef.Name;
            result["Type"] = MapCLRTypeToJS(fdef.NonNullableType);
            var key = fdef.AnyTargetKey;

            if (key)
            {
                result["Key"] = key;
            }


            if (fdef.NonNullableType.IsEnum)
            { //Generate default lookupdict for enum
                var names  = Enum.GetNames(fdef.NonNullableType);
                var values = new JSONDataMap(true);
                foreach (var name in names)
                {
                    values[name] = name;
                }

                result["LookupDict"] = values;
            }

            var attr = fdef[target];

            if (attr != null)
            {
                if (attr.Description != null)
                {
                    result["Description"] = OnLocalizeString(schema, "Description", attr.Description, isoLang);
                }
                var str = attr.StoreFlag == StoreFlag.OnlyStore || attr.StoreFlag == StoreFlag.LoadAndStore;
                if (!str)
                {
                    result["Stored"] = str;
                }
                if (attr.Required)
                {
                    result["Required"] = attr.Required;
                }
                if (!attr.Visible)
                {
                    result["Visible"] = attr.Visible;
                }
                if (attr.Min != null)
                {
                    result["MinValue"] = attr.Min;
                }
                if (attr.Max != null)
                {
                    result["MaxValue"] = attr.Max;
                }
                if (attr.MinLength > 0)
                {
                    result["MinSize"] = attr.MinLength;
                }
                if (attr.MaxLength > 0)
                {
                    result["Size"] = attr.MaxLength;
                }
                if (attr.Default != null)
                {
                    result["DefaultValue"] = attr.Default;
                }
                if (attr.ValueList.IsNotNullOrWhiteSpace())
                {
                    var vl = OnLocalizeString(schema, "LookupDict", attr.ValueList, isoLang);
                    result["LookupDict"] = FieldAttribute.ParseValueListString(vl);
                }
                if (attr.Kind != DataKind.Text)
                {
                    result["Kind"] = MapCLRKindToJS(attr.Kind);
                }
            }

            if (attr.Metadata != null)
            {
                foreach (var fn in METADATA_FIELDS)
                {
                    var mv = attr.Metadata.AttrByName(fn).Value;
                    if (mv.IsNullOrWhiteSpace())
                    {
                        continue;
                    }

                    if (fn == "Description" || fn == "Placeholder" || fn == "LookupDict" || fn == "Hint")
                    {
                        mv = OnLocalizeString(schema, fn, mv, isoLang);
                    }

                    result[fn] = mv;
                }
            }


            return(result);
        }
示例#19
0
    /// <summary>
    /// Makes CRUD Schema out of BSON document. The types of all fields are object as documents do not have
    ///  a predictable type of every field (they are dynamic and can change form doc to doc)
    /// </summary>
    public virtual Schema InferSchemaFromBSONDocument(BSONDocument doc, string schemaName = null)
    {
      var defs = new List<Schema.FieldDef>();

      foreach(var elm in doc)
      {
          var clrv = elm.ObjectValue;
          var tv = typeof(object);
          var def = new Schema.FieldDef(elm.Name, tv, new FieldAttribute[]{ new FieldAttribute(backendName: elm.Name) });
          defs.Add( def );
      }

      return  new Schema(schemaName.IsNotNullOrWhiteSpace() ? schemaName : Guid.NewGuid().ToString(),
                         true,
                         defs.ToArray());
    }
示例#20
0
文件: SchemaMap.cs 项目: yhhno/nfx
    public static Schema ErlSchemaToCRUDSchema(string name, IConfigSectionNode erlSect)
    {
      var defs       = new List<Schema.FieldDef>();

      var isInsert   = erlSect.AttrByName(CONFIG_INSERT_ATTR).ValueAsBool(false);
      var isUpdate   = erlSect.AttrByName(CONFIG_UPDATE_ATTR).ValueAsBool(false);
      var isDelete   = erlSect.AttrByName(CONFIG_DELETE_ATTR).ValueAsBool(false);
      var schDescr   = erlSect.AttrByName(CONFIG_DESCR_ATTR).ValueAsString();

      var isReadonly = !(isInsert || isUpdate || isDelete);

      var keyCount = 0;
      var nodeFields = erlSect.Children.Where(c => c.IsSameName(CONFIG_FIELD_SECTION));
      foreach(var nodeField in nodeFields)
      {
        var cfg      = new LaconicConfiguration();
        cfg.CreateFromNode(nodeField);
        var node     = cfg.Root;

        var fname    = node.AttrByName(Configuration.CONFIG_NAME_ATTR).Value;
        var ftitle   = node.AttrByName(CONFIG_TITLE_ATTR).Value;
        var fhint    = node.AttrByName(CONFIG_DESCR_ATTR).ValueAsString("");
        var isKey    = node.AttrByName(CONFIG_KEY_ATTR).ValueAsBool();
        var required = node.AttrByName(CONFIG_REQUIRED_ATTR).ValueAsBool(false);
        var type     = node.AttrByName(CONFIG_TYPE_ATTR).Value;
        var clrType  = mapErlTypeToCLR(type);
        var fmtdesc  = node.AttrByName(CONFIG_FORMAT_DESCR_ATTR).Value;
        var dispFmt  = node.AttrByName(CONFIG_DISPLAY_FORMAT_ATTR).Value;

        if (dispFmt != null && (dispFmt.Length < 3 || dispFmt.Substring(0, 3) != "{0:"))
          dispFmt = "{{0:{0}}}".Args(dispFmt);

        node.AddAttributeNode(CONFIG_TITLE_ATTR, ftitle);

        object minV  = null;
        object maxV  = null;

        var sv = node.AttrByName(CONFIG_MIN_ATTR).Value;
        if (sv.IsNotNullOrWhiteSpace()) minV = sv.AsType(clrType, true);

        sv = node.AttrByName(CONFIG_MAX_ATTR).Value;
        if (sv.IsNotNullOrWhiteSpace()) maxV = sv.AsType(clrType, true);


        var strDfltValue = node.AttrByName(CONFIG_DEFAULT_ATTR).ValueAsString(string.Empty);
        object dfltValue = null;
          
        if (clrType==typeof(string))
          dfltValue = strDfltValue;
        else if (strDfltValue.IsNotNullOrWhiteSpace())
          dfltValue = clrType==typeof(DateTime?) 
                    ? ((long)strDfltValue.AsType(typeof(long), false)).FromMicrosecondsSinceUnixEpochStart() 
                    : strDfltValue.AsType(clrType, false);

        if (isKey) keyCount++;

        List<string> vList = null;
                   
        var values = node.Children.Where( c => c.IsSameName(CONFIG_VALUE_SECTION));
        foreach(var vnode in values)
        {
          var code = vnode.AttrByName(CONFIG_CODE_ATTR).Value;
          var disp = vnode.AttrByName(CONFIG_DISPLAY_ATTR).Value;
          if (code.IsNullOrWhiteSpace()) continue;

          if (vList==null) vList = new List<string>();
          if (disp.IsNullOrWhiteSpace())
            vList.Add(code);
          else
            vList.Add("{0}: {1}".Args(code, disp));
        }

        var caze = CharCase.AsIs;

        var ca = node.AttrByName(CONFIG_CASE_ATTR).Value;
        if (ca.EqualsOrdIgnoreCase("upper")) caze = CharCase.Upper;
        else
        if (ca.EqualsOrdIgnoreCase("lower")) caze = CharCase.Lower;

        var atr = new FieldAttribute(
            targetName:    TargetedAttribute.ANY_TARGET, 
            backendName:   fname,
            backendType:   type,
            storeFlag:     StoreFlag.LoadAndStore,
            key:           isKey,
            required:      required,
            dflt:          dfltValue,
                             
            min:           minV,
            max:           maxV,
                             
            charCase:      caze,

            visible:       node.AttrByName(CONFIG_VISIBLE_ATTR).ValueAsBool(true),
            maxLength:     node.AttrByName(CONFIG_LEN_ATTR).ValueAsInt(0),
            description:   fmtdesc.IsNullOrEmpty() ? fhint : "{0}\nFormat: {1}".Args(fhint,fmtdesc),
                            //Parsing.Utils.ParseFieldNameToDescription(ftitle, true),
            formatRegExp:  node.AttrByName(CONFIG_FORMAT_ATTR).Value,
            formatDescr:   fmtdesc,
            displayFormat: dispFmt,
            valueList:     vList==null ? null : string.Join(",", vList),//"CAR: Car Driver,SMK: Smoker, REL: Religious, CNT: Country music lover, GLD: Gold collector"
            metadata:      node.ToLaconicString());

        var def = new Schema.FieldDef(fname, clrType, new []{atr});
        defs.Add( def );
      }//for fields 

      var result = new Schema(name, isReadonly, defs.ToArray());

      if (schDescr.IsNotNullOrWhiteSpace())
        result.ExtraData[CONFIG_DESCR_ATTR]               = schDescr;

      result.ExtraData[SCHEMA_KEY_COUNT]                  = keyCount; 
      result.ExtraData[Schema.EXTRA_SUPPORTS_INSERT_ATTR] = isInsert;
      result.ExtraData[Schema.EXTRA_SUPPORTS_UPDATE_ATTR] = isUpdate;
      result.ExtraData[Schema.EXTRA_SUPPORTS_DELETE_ATTR] = isDelete;

      return result;
    }