Exemple #1
0
        public void ExprEval1_TernaryIf()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
                @"
root
{
   a=12
   b=true

   var1=0{script-only=true}
   var2=175.4{script-only=true}
   var3=true{script-only=true}

   _block
   {
       _set{ path=/var1 to=(?$(/var2)>10;15;-10)+100 }
       RESULT=$(/var1){}
   }
}
");
            var result = new NFX.Environment.LaconicConfiguration();

            new ScriptRunner().Execute(src, result);

            var got = result.SaveToString();

            Console.WriteLine(got);

            Aver.AreEqual(115, result.Root["RESULT"].ValueAsInt());
        }
Exemple #2
0
        /// <summary>
        /// Initializes local installation, tries to read local manifest from rootPath or localManifestDir if it is !=null
        /// </summary>
        public LocalInstallation(string rootPath, string localManifestDir = null)
        {
            if (rootPath.IsNullOrWhiteSpace())
              throw new NFXIOException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".ctor(rootPath==null|empty)");

            var parent = Directory.GetParent(rootPath);
            if (!parent.Exists)
              throw new NFXIOException(StringConsts.LOCAL_INSTALL_ROOT_PATH_NOT_FOUND_ERROR.Args(parent.FullName));

            m_RootPath = rootPath;

            var manifestDir = localManifestDir.IsNotNullOrWhiteSpace() ? localManifestDir : m_RootPath;

            if (Directory.Exists(manifestDir))
            {
              var fn = Path.Combine(manifestDir, ManifestUtils.MANIFEST_FILE_NAME);
              if (File.Exists(fn))
              try
              {
             m_Packages = new LaconicConfiguration(fn).Root;
              }
              catch(Exception error)
              {
            throw new NFXIOException(StringConsts.LOCAL_INSTALL_LOCAL_MANIFEST_READ_ERROR.Args(fn, error.ToMessageWithType()), error);
              }
            }

            if (m_Packages==null)
            {
              var cfg = new LaconicConfiguration();
              cfg.Create(ManifestUtils.CONFIG_PACKAGES_SECTION);
              m_Packages = cfg.Root;
            }
        }
Exemple #3
0
        /// <summary>
        /// Creates a new empty config root based on laconic format
        /// </summary>
        public static ConfigSectionNode NewEmptyRoot(string name = null)
        {
            var cfg = new LaconicConfiguration();

            cfg.Create(name);
            return(cfg.Root);
        }
            /// <summary>
            /// Creates an instance of configuration initialized from laconfig passed as string
            /// </summary>
            public static LaconicConfiguration CreateFromString(string content)
            {
              var result = new LaconicConfiguration();
              result.readFromString(content);

              return result;
            }
Exemple #5
0
        public void ExprEval1_TernaryIfWithMixingTypes()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
                @"
root
{
   a=12
   b=true

   var1=0{script-only=true}
   var2=175.4{script-only=true}
   var3=true{script-only=true}

   _block
   {
       _set{ path=/var1 to='((?$(/var3);$(/var2);-10)+100)+kozel' }
       RESULT=$(/var1){}
   }
}
");
            var result = new NFX.Environment.LaconicConfiguration();

            new ScriptRunner().Execute(src, result);

            var got = result.SaveToString();

            Console.WriteLine(got);

            Assert.AreEqual("275.4kozel", result.Root["RESULT"].Value);
        }
Exemple #6
0
        /// <summary>
        /// Loads the supplied string content in the specified format, which may be format name like "xml" or "laconfig" with or without extension period
        /// </summary>
        public static Configuration ProviderLoadFromString(string content, string format)
        {
            if (format.StartsWith("."))
            {
                format = format.Remove(0, 1);
            }

            //since C# does not support first-class types, these if statements below must handle what AllSupportedFormat returns
            //in future Aum conversion replace with Dictionary<format, configType> lookup

            if (NFX.CodeAnalysis.Laconfig.LaconfigLanguage.Instance.FileExtensions.Any(e => string.Equals(e, format, StringComparison.InvariantCultureIgnoreCase)))
            {
                return(LaconicConfiguration.CreateFromString(content));
            }

            if (NFX.CodeAnalysis.XML.XMLLanguage.Instance.FileExtensions.Any(e => string.Equals(e, format, StringComparison.InvariantCultureIgnoreCase)))
            {
                return(XMLConfiguration.CreateFromXML(content));
            }

            if (NFX.CodeAnalysis.JSON.JSONLanguage.Instance.FileExtensions.Any(e => string.Equals(e, format, StringComparison.InvariantCultureIgnoreCase)))
            {
                return(JSONConfiguration.CreateFromJSON(content));
            }

            throw new ConfigException(StringConsts.CONFIG_NO_PROVIDER_LOAD_FORMAT_ERROR + format);
        }
Exemple #7
0
        public void SectionNameWithVar()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
                @"
root
{
       i=0
       _loop=$(/$i)<10
       {
           section_$(/$i) {}
           _set{path=/$i to=$(/$i)+1}
       }
}
");
            var result = new NFX.Environment.LaconicConfiguration();

            new ScriptRunner().Execute(src, result);

            var got = result.SaveToString();

            Console.WriteLine(got);

            Assert.AreEqual("section_0", result.Root[0].Name);
            Assert.AreEqual("section_9", result.Root[9].Name);
            Assert.IsFalse(result.Root[10].Exists);
        }
Exemple #8
0
        public void LoopWithRealArithmetic()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
                @"
root
{
       i=0
       _loop='$(/$i)<=1.2'
       {
           section_$(/$i) {}
           _set{path=/$i to=$(/$i)+0.2}
       }
}
");
            var result = new NFX.Environment.LaconicConfiguration();

            new ScriptRunner().Execute(src, result);

            var got = result.SaveToString();

            Console.WriteLine(got);

            Assert.AreEqual("section_0", result.Root[0].Name);
            Assert.AreEqual("section_0.2", result.Root[1].Name);
            Assert.AreEqual("section_0.4", result.Root[2].Name);
            Assert.AreEqual("section_0.6", result.Root[3].Name);
            Assert.AreEqual("section_0.8", result.Root[4].Name);
            Assert.AreEqual("section_1", result.Root[5].Name);
            Assert.AreEqual("section_1.2", result.Root[6].Name);
            Assert.IsFalse(result.Root[7].Exists);
        }
Exemple #9
0
        /// <summary>
        /// Creates an instance of configuration initialized from laconfig passed as string
        /// </summary>
        public static LaconicConfiguration CreateFromString(string content)
        {
            var result = new LaconicConfiguration();

            result.readFromString(content);

            return(result);
        }
Exemple #10
0
        public void VarsLoopIfElseCall()
        {
            var src    = NFX.Environment.LaconicConfiguration.CreateFromString(src1);
            var result = new NFX.Environment.LaconicConfiguration();

            new ScriptRunner().Execute(src, result);

            var got = result.SaveToString();

            Console.WriteLine(got);
            Assert.AreEqual(expected1, got);
        }
Exemple #11
0
        public void RSchema()
        {
            var src    = NFX.Environment.LaconicConfiguration.CreateFromString(rschema);
            var result = new NFX.Environment.LaconicConfiguration();

            new ScriptRunner().Execute(src, result);

            var got = result.SaveToString();

            Console.WriteLine(got);
            Assert.AreEqual(rschemaExpected, got);
        }
Exemple #12
0
        public void Error_Timeout()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
                @"
root
{
       _loop=true {}
}
");
            var result = new NFX.Environment.LaconicConfiguration();

            new ScriptRunner().Execute(src, result);
        }
Exemple #13
0
        public void Error_ELSEWithoutIF()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
                @"
root
{
       _else{  }
}
");
            var result = new NFX.Environment.LaconicConfiguration();

            new ScriptRunner().Execute(src, result);
        }
Exemple #14
0
        public void Error_SetVarDoesNotExist()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
                @"
root
{
       _set{ path=/NONE to=5+5 }
}
");
            var result = new NFX.Environment.LaconicConfiguration();

            new ScriptRunner().Execute(src, result);
        }
Exemple #15
0
 private void btnScripting_Click(object sender, EventArgs e)
 {
     try
     {
         var src = LaconicConfiguration.CreateFromString(this.sourceScripting.Text);
         var res = new LaconicConfiguration();
         var runner = new ScriptRunner();
         runner.TimeoutMs = 500; // for slow computers may be increased
         runner.Execute(src, res);
         this.resultScripting.Text = res.SaveToString();
     }
     catch (Exception ex)
     {
         this.resultScripting.Text = ex.ToMessageWithType();
     }
 }
Exemple #16
0
        public void Error_ELSEWithoutIF2()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
            @"
            root
            {
               _if=true{}
               in-the-middle{}
               _else{  }
            }
            ");
              var result = new NFX.Environment.LaconicConfiguration();

              new ScriptRunner().Execute(src, result);
        }
Exemple #17
0
        public void Error_SetVarDoesNotExist()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
            @"
            root
            {
               _set{ path=/NONE to=5+5 }
            }
            ");
              var result = new NFX.Environment.LaconicConfiguration();

              new ScriptRunner().Execute(src, result);
        }
Exemple #18
0
        public void SaveToString()
        {
            var conf = new LaconicConfiguration();
              conf.Create("very-root");
              conf.Root.AddChildNode("childSection1").AddAttributeNode("name", "Alex");
              conf.Root.AddChildNode("child2").AddAttributeNode("name", "Boris");
              conf.Root["child2"].Value = "Muxa";

              var child3 = conf.Root.AddChildNode("child3");
              child3.AddAttributeNode("atr with space", 1);
              child3.AddAttributeNode("atr2", "val with space");
              child3.AddAttributeNode("atr{3}", null);
              child3.AddAttributeNode("atr=4", null);

              child3.AddAttributeNode("atr5", "this goes on \n\r new\\next line");

              child3.AddChildNode("child3.1");
              child3.AddChildNode("child3.2").AddChildNode("child3.2.1");
              child3.AddChildNode("child3.3");

              var txt = conf.SaveToString(LaconfigWritingOptions.PrettyPrint);
              Console.WriteLine(txt);
              Assert.AreEqual(
            @"very-root
            {
              childSection1
              {
            name=Alex
              }
              child2=Muxa
              {
            name=Boris
              }
              child3
              {
            ""atr with space""=1
            atr2=""val with space""
            ""atr{3}""=''
            ""atr=4""=''
            atr5=""this goes on \n\r new\\next line""
            child3.1
            {
            }
            child3.2
            {
              child3.2.1
              {
              }
            }
            child3.3
            {
            }
              }
            }", txt);

            txt = conf.SaveToString(LaconfigWritingOptions.Compact);

            Console.WriteLine(txt);

            Assert.AreEqual(
             @"very-root{childSection1{name=Alex}child2=Muxa{name=Boris}child3{""atr with space""=1 atr2=""val with space"" ""atr{3}""='' ""atr=4""='' atr5=""this goes on \n\r new\\next line"" child3.1{}child3.2{child3.2.1{}}child3.3{}}}",
               txt);
        }
Exemple #19
0
        public void Error_Timeout()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
            @"
            root
            {
               _loop=true {}
            }
            ");
              var result = new NFX.Environment.LaconicConfiguration();

              new ScriptRunner().Execute(src, result);
        }
Exemple #20
0
        public FieldAttribute(
                        Type protoType, 
                        string protoFieldName, //Schema:Field
                        string targetName   = ANY_TARGET,
                        object storeFlag    = null,
                        object key          = null,
                        object kind         = null,
                        object required     = null,
                        object visible      = null,
                        string valueList    = null,
                        object dflt         = null,
                        object min          = null,
                        object max          = null,
                        object minLength    = null,
                        object maxLength    = null,
                        object charCase     = null,
                        string backendName  = null,
                        string description  = null,
                        string metadata     = null,
                        object nonUI        = null
                    ) : base(targetName, null)
        {
            if (protoType==null || protoFieldName.IsNullOrWhiteSpace()) throw new CRUDException(StringConsts.ARGUMENT_ERROR+"FieldAttr.ctor(protoType|protoFieldName=null|empty)");
            try
            {
              var schema = Schema.GetForTypedRow(protoType);
              var protoTargetName = targetName;
              var segs = protoFieldName.Split(':');
              if (segs.Length>1)
              {
                protoTargetName = segs[0].Trim();
                protoFieldName = segs[1].Trim();
              }
              if (protoTargetName.IsNullOrWhiteSpace()) throw new Exception("Wrong target syntax");
              if (protoFieldName.IsNullOrWhiteSpace()) throw new Exception("Wrong field syntax");

              var protoFieldDef = schema[protoFieldName];
              if (protoFieldDef==null) throw new Exception("Prototype '{0}' field '{1}' not found".Args(protoType.FullName, protoFieldName));
              var protoAttr = protoFieldDef[protoTargetName];
            
              try
              {
                StoreFlag        = storeFlag    == null? protoAttr.StoreFlag   : (StoreFlag)storeFlag     ;
                BackendName      = backendName  == null? protoAttr.BackendName : backendName   ;
                Key              = key          == null? protoAttr.Key         : (bool)key           ;
                Kind             = kind         == null? protoAttr.Kind        : (DataKind)kind          ;
                Required         = required     == null? protoAttr.Required    : (bool)required      ;
                Visible          = visible      == null? protoAttr.Visible     : (bool)visible       ;
                Min              = min          == null? protoAttr.Min         : min           ;
                Max              = max          == null? protoAttr.Max         : max           ;
                Default          = dflt         == null? protoAttr.Default     : dflt          ;
                MinLength        = minLength    == null? protoAttr.MinLength   : (int)minLength     ;
                MaxLength        = maxLength    == null? protoAttr.MaxLength   : (int)maxLength     ;
                CharCase         = charCase     == null? protoAttr.CharCase    : (CharCase)charCase      ;
                ValueList        = valueList    == null? protoAttr.ValueList   : valueList     ;
                Description      = description  == null? protoAttr.Description : description   ;
                NonUI            = nonUI        == null? protoAttr.NonUI       : (bool)nonUI         ;
                
                if (metadata.IsNullOrWhiteSpace())
                 m_MetadataContent = protoAttr.m_MetadataContent;
                else
                if (protoAttr.m_MetadataContent.IsNullOrWhiteSpace()) m_MetadataContent = metadata;
                else
                {
                  var conf1 = ParseMetadataContent(protoAttr.m_MetadataContent);
                  var conf2 = ParseMetadataContent(metadata);
                  
                  var merged = new LaconicConfiguration();
                  merged.CreateFromMerge(conf1, conf2);
                  m_MetadataContent = merged.SaveToString();
                }
              }
              catch(Exception err)
              {
                throw new Exception("Invalid assignment of prototype override value: " + err.ToMessageWithType());
              }
            }
            catch(Exception error)
            {
              throw new CRUDException(StringConsts.CRUD_FIELD_ATTR_PROTOTYPE_CTOR_ERROR.Args(error.Message));
            }

        }
Exemple #21
0
        public void RSchema()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString( rschema );
              var result = new NFX.Environment.LaconicConfiguration();

              new ScriptRunner().Execute(src, result);

              var got =  result.SaveToString();
              Console.WriteLine( got );
              Assert.AreEqual(rschemaExpected, got);
        }
Exemple #22
0
        public void LoopWithRealArithmetic()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
            @"
            root
            {
               i=0
               _loop='$(/$i)<=1.2'
               {
               section_$(/$i) {}
               _set{path=/$i to=$(/$i)+0.2}
               }
            }
            ");
              var result = new NFX.Environment.LaconicConfiguration();

              new ScriptRunner().Execute(src, result);

              var got =  result.SaveToString();
              Console.WriteLine( got );

              Assert.AreEqual("section_0", result.Root[0].Name);
              Assert.AreEqual("section_0.2", result.Root[1].Name);
              Assert.AreEqual("section_0.4", result.Root[2].Name);
              Assert.AreEqual("section_0.6", result.Root[3].Name);
              Assert.AreEqual("section_0.8", result.Root[4].Name);
              Assert.AreEqual("section_1", result.Root[5].Name);
              Assert.AreEqual("section_1.2", result.Root[6].Name);
              Assert.IsFalse( result.Root[7].Exists);
        }
Exemple #23
0
        public void ExprEval1_TernaryIfWithMixingTypes()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
            @"
            root
            {
               a=12
               b=true

               var1=0{script-only=true}
               var2=175.4{script-only=true}
               var3=true{script-only=true}

               _block
               {
               _set{ path=/var1 to='((?$(/var3);$(/var2);-10)+100)+kozel' }
               RESULT=$(/var1){}
               }
            }
            ");
              var result = new NFX.Environment.LaconicConfiguration();

              new ScriptRunner().Execute(src, result);

              var got =  result.SaveToString();
              Console.WriteLine( got );

              Assert.AreEqual("275.4kozel", result.Root["RESULT"].Value);
        }
Exemple #24
0
        public void SectionNameWithVar()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(
            @"
            root
            {
               i=0
               _loop=$(/$i)<10
               {
               section_$(/$i) {}
               _set{path=/$i to=$(/$i)+1}
               }
            }
            ");
              var result = new NFX.Environment.LaconicConfiguration();

              new ScriptRunner().Execute(src, result);

              var got =  result.SaveToString();
              Console.WriteLine( got );

              Assert.AreEqual("section_0", result.Root[0].Name);
              Assert.AreEqual("section_9", result.Root[9].Name);
              Assert.IsFalse( result.Root[10].Exists);
        }
Exemple #25
0
        public void SaveToPrettyStringThenReadBack()
        {
            var conf = new LaconicConfiguration();
              conf.Create("very-root");
              conf.Root.AddChildNode("childSection1").AddAttributeNode("name", "Alex");
              conf.Root.AddChildNode("child2").AddAttributeNode("name", "Boris");
              conf.Root["child2"].Value = "Muxa";

              var child3 = conf.Root.AddChildNode("child3");
              child3.AddAttributeNode("atr with space", 1);
              child3.AddAttributeNode("atr2", "val with space");
              child3.AddAttributeNode("atr{3}", null);
              child3.AddAttributeNode("atr=4", null);

              child3.AddAttributeNode("atr5", "this goes on \n\r new\\next line");

              child3.AddChildNode("child3.1");
              child3.AddChildNode("child3.2").AddChildNode("child3.2.1");
              child3.AddChildNode("child3.3");

              var txt =  conf.SaveToString(LaconfigWritingOptions.PrettyPrint);

              var conf2 = LaconicConfiguration.CreateFromString(txt);

              Assert.IsTrue(conf2.Root["childSection1"].Exists);
              Assert.IsTrue(conf2.Root["child3"].AttrByName("atr with space").Exists);
              Assert.IsTrue(conf2.Root.Navigate("childSection1/$name").Exists);
              Assert.IsTrue(conf2.Root.Navigate("child2/$name").Exists);
              Assert.IsTrue(conf2.Root.Navigate("child3/$atr{3}").Exists);
              Assert.IsTrue(conf2.Root.Navigate("child3/child3.2/child3.2.1").Exists);

              Assert.AreEqual("Muxa", conf2.Root.Navigate("child2").Value);
              Assert.AreEqual("1", conf2.Root.Navigate("child3/$atr with space").Value);
              Assert.AreEqual("val with space", conf2.Root.Navigate("child3/$atr2").Value);
              Assert.IsTrue( conf2.Root.Navigate("child3/$atr=4").Value.IsNullOrWhiteSpace() );
        }
Exemple #26
0
        public void VarsLoopIfElseCall()
        {
            var src = NFX.Environment.LaconicConfiguration.CreateFromString(src1);
              var result = new NFX.Environment.LaconicConfiguration();

              new ScriptRunner().Execute(src, result);

              var got =  result.SaveToString();
              Console.WriteLine( got );
              Assert.AreEqual(expected1, got);
        }
Exemple #27
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;
    }