private Schema(Type tdoc) { lock (s_TypeLatch) { if (s_TypeLatch.Contains(tdoc)) { throw new DataException(StringConsts.CRUD_TYPED_DOC_RECURSIVE_FIELD_DEFINITION_ERROR.Args(tdoc.FullName)); } s_TypeLatch.Add(tdoc); try { m_Name = tdoc.AssemblyQualifiedName; var tattrs = tdoc.GetCustomAttributes(typeof(TableAttribute), false).Cast <TableAttribute>(); m_TableAttrs = new List <TableAttribute>(tattrs); m_FieldDefs = new OrderedRegistry <FieldDef>(); var props = GetFieldMembers(tdoc); var order = 0; foreach (var prop in props) { var fattrs = prop.GetCustomAttributes(typeof(FieldAttribute), false) .Cast <FieldAttribute>() .ToArray(); //20160318 DKh. Interpret [Field(CloneFromType)] for (var i = 0; i < fattrs.Length; i++) { var attr = fattrs[i]; if (attr.CloneFromDocType == null) { continue; } if (fattrs.Length > 1) { throw new DataException(StringConsts.CRUD_TYPED_DOC_SINGLE_CLONED_FIELD_ERROR.Args(tdoc.FullName, prop.Name)); } var clonedSchema = Schema.GetForTypedDoc(attr.CloneFromDocType); var clonedDef = clonedSchema[prop.Name]; if (clonedDef == null) { throw new DataException(StringConsts.CRUD_TYPED_DOC_CLONED_FIELD_NOTEXISTS_ERROR.Args(tdoc.FullName, prop.Name)); } fattrs = clonedDef.Attrs.ToArray();//replace these attrs from the cloned target break; } var fdef = new FieldDef(prop.Name, order, prop.PropertyType, fattrs, prop); m_FieldDefs.Register(fdef); order++; } s_TypedRegistry.Register(this); m_TypedDocType = tdoc; } finally { s_TypeLatch.Remove(tdoc); } } //lock }
/// <summary> /// Creates an empty table /// </summary> public Table(Schema schema) : base(schema) { m_List = new List <Doc>(); }
/// <summary> /// Writes fielddef as JSON. Do not call this method directly, instead call rowset.ToJSON() or use JSONWriter class /// </summary> void IJsonWritable.WriteAsJson(System.IO.TextWriter wri, int nestingLevel, JsonWritingOptions options) { var attr = this[null]; if (attr != null && attr.NonUI) { wri.Write("{}"); return; //nothing to write for NONUI } bool typeIsNullable; string tp = JSONMappings.MapCLRTypeToJSON(m_Type, out typeIsNullable); var map = new Dictionary <string, object> { { "Name", m_Name }, { "Order", m_Order }, { "Type", tp }, { "Nullable", typeIsNullable } }; //20190322 DKh inner schema if (typeof(Doc).IsAssignableFrom(this.NonNullableType)) { map["IsDataDoc"] = true; map["IsAmorphous"] = typeof(IAmorphousData).IsAssignableFrom(this.NonNullableType); map["IsForm"] = typeof(Form).IsAssignableFrom(this.NonNullableType); if (typeof(TypedDoc).IsAssignableFrom(this.NonNullableType)) { var innerSchema = Schema.GetForTypedDoc(this.NonNullableType); if (innerSchema.Any(fd => typeof(TypedDoc).IsAssignableFrom(fd.Type))) { map["DataDocSchema"] = "@complex"; } else { map["DataDocSchema"] = innerSchema; } } } if (attr != null) { map.Add("IsKey", attr.Key); map.Add("IsRequired", attr.Required); map.Add("Visible", attr.Visible); if (attr.Default != null) { map.Add("Default", attr.Default); } if (attr.CharCase != CharCase.AsIs) { map.Add("CharCase", attr.CharCase); } if (attr.Kind != DataKind.Text) { map.Add("Kind", attr.Kind); } if (attr.MinLength != 0) { map.Add("MinLen", attr.MinLength); } if (attr.MaxLength != 0) { map.Add("MaxLen", attr.MaxLength); } if (attr.Min != null) { map.Add("Min", attr.Min); } if (attr.Max != null) { map.Add("Max", attr.Max); } if (attr.ValueList != null) { map.Add("ValueList", attr.ValueList); } if (attr.Description != null) { map.Add("Description", attr.Description); } //metadata content is in the internal format and not dumped } JsonWriter.WriteMap(wri, map, nestingLevel, options); }