Esempio n. 1
0
        /// <summary>
        /// Create a foreign key constraint on two tables.
        /// </summary>
        /// <param name="dataModelSchema">The parent data model schema.</param>
        /// <param name="xmlSchemaKeyref">The XmlSchema object that describes the foreignn key relation.</param>
        public ForeignKeyConstraintSchema(DataModelSchema dataModelSchema, XmlSchemaKeyref xmlSchemaKeyref)
            : base(dataModelSchema, xmlSchemaKeyref)
        {
            // This will search through each of the tables looking for a key that matches the name of the reference.  Note that
            // there is no checking to make sure the 'Refer' key exists.  If it didn't exist, the XmlSchema would have caught it
            // and never have validated the schema.
            foreach (KeyValuePair <string, TableSchema> keyValuePair in dataModelSchema.Tables)
            {
                ConstraintSchema constraintSchema;
                if (keyValuePair.Value.Constraints.TryGetValue(xmlSchemaKeyref.Refer.Name, out constraintSchema))
                {
                    this.relatedTable   = constraintSchema.Table;
                    this.relatedColumns = constraintSchema.Columns;
                }
            }

            // Parse the cascading update rule out of the keyref specification.
            XmlAttribute updateRuleAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaKeyref, QualifiedName.UpdateRule);

            this.updateRule = updateRuleAttribute == null ? CascadeRules.Cascade : (CascadeRules)Enum.Parse(typeof(CascadeRules), updateRuleAttribute.Value);

            // Parse the cascading delete rule out of the keyref specification.
            XmlAttribute deleteRuleAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaKeyref, QualifiedName.DeleteRule);

            this.deleteRule = deleteRuleAttribute == null ? CascadeRules.Cascade : (CascadeRules)Enum.Parse(typeof(CascadeRules), deleteRuleAttribute.Value);
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a constraint that forces a set of columns to be unique.
        /// </summary>
        /// <param name="dataModelSchema">The parent data model schema.</param>
        /// <param name="xmlSchemaUnique">The XmlSchema description of the constraint.</param>
        public UniqueConstraintSchema(DataModelSchema dataModelSchema, XmlSchemaUnique xmlSchemaUnique)
            : base(dataModelSchema, xmlSchemaUnique)
        {
            // This determines whether the constraint should be used as the primary key for a table.
            XmlAttribute xmlAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaUnique, QualifiedName.PrimaryKey);

            this.isPrimaryKey = xmlAttribute == null ? false : Convert.ToBoolean(xmlAttribute.Value);
        }
Esempio n. 3
0
        public bool GetPrimaryKeyStatus(XmlSchemaIdentityConstraint xmlSchemaIdentityConstraint)
        {
            XmlAttribute xmlAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaIdentityConstraint, QualifiedName.PrimaryKey);

            if (xmlAttribute != null)
            {
                return(Convert.ToBoolean(xmlAttribute.Value));
            }

            return(false);
        }
Esempio n. 4
0
        /// <summary>
        /// Indicates whether the column is persisted in a data store.
        /// </summary>
        /// <param name="xmlSchemaElement">The XML Element.</param>
        /// <returns>true if the column should be stored in a persistent database.</returns>
        private bool GetPersistentIndicator(XmlSchemaElement xmlSchemaElement)
        {
            // Extract the persistence attribute of a column.
            XmlAttribute xmlAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaElement, QualifiedName.IsPersistent);

            if (xmlAttribute != null)
            {
                return(Convert.ToBoolean(xmlAttribute.Value));
            }

            // The default attribute is to generate a persistent table.
            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Creates a collection of tables found in the schema.
        /// </summary>
        /// <param name="xmlSchema">The schema that describes the data model.</param>
        /// <returns>A list of TableSchema objects that describe the tables found in the data model schema.</returns>
        private void FirstPass(XmlSchemaSet xmlSchemaSet)
        {
            // Scan through the schema set looking for table elements.  These can either be defined at the root element for a standard
            // schema or they can be found as choices of a special element describing a 'DataSet' for the Microsoft version of a
            // schema.
            foreach (XmlSchemaElement xmlSchemaElement in xmlSchemaSet.GlobalElements.Values)
            {
                // If the element read from the schema is the Microsoft DataSet element, then the tables are described as choices
                // associated with an implicit complex type on that element.
                if (ObjectSchema.IsDataSetElement(xmlSchemaElement))
                {
                    // The tables are described as an choices of an implicit (nested) complex type.
                    if (xmlSchemaElement.SchemaType is XmlSchemaComplexType)
                    {
                        // The complex type describes the table.
                        XmlSchemaComplexType xmlSchemaComplexType = xmlSchemaElement.SchemaType as XmlSchemaComplexType;

                        // The data model is described as a set of one or more choices of tables.
                        if (xmlSchemaComplexType.Particle is XmlSchemaChoice)
                        {
                            // The data model is described as a set of choices.  Each choice represents a table.
                            XmlSchemaChoice xmlSchemaChoice = xmlSchemaComplexType.Particle as XmlSchemaChoice;

                            // Create a table for each of the choices described in the complex type.
                            foreach (XmlSchemaObject choiceObject in xmlSchemaChoice.Items)
                            {
                                if (choiceObject is XmlSchemaElement)
                                {
                                    XmlSchemaElement tableElement = choiceObject as XmlSchemaElement;
                                    this.tableList.Add(tableElement.Name, new TableSchema(this, tableElement));
                                }
                            }
                        }
                    }

                    // The constraints describe the columns that are unique for a table.
                    foreach (XmlSchemaIdentityConstraint xmlSchemaIdentityConstraint in xmlSchemaElement.Constraints)
                    {
                        // This describes the columns that must be unique within a table.
                        if (xmlSchemaIdentityConstraint is XmlSchemaUnique)
                        {
                            XmlSchemaUnique        xmlSchemaUnique        = xmlSchemaIdentityConstraint as XmlSchemaUnique;
                            UniqueConstraintSchema uniqueConstraintSchema = new UniqueConstraintSchema(this, xmlSchemaUnique);
                            uniqueConstraintSchema.Table.Add(uniqueConstraintSchema);
                        }
                    }
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// The foreign constraints can only be evaluated after all the tables, keys and unique constraints have been evaluated.
        /// </summary>
        /// <param name="xmlSchema"></param>
        private void SecondPass(XmlSchemaSet xmlSchemaSet)
        {
            // This is the second pass through the schemas.  Once the tables, keys and unique constraints have been evaluated,
            // then the foreign constraints can be constructed and applied to the parent and child tables.
            foreach (XmlSchemaElement xmlSchemaElement in xmlSchemaSet.GlobalElements.Values)
            {
                // Only the Microsoft DataSet element is evaluated for foreign keys.
                if (ObjectSchema.IsDataSetElement(xmlSchemaElement))
                {
                    // This will examine each of the constraints looking for a foreign key description.
                    foreach (XmlSchemaIdentityConstraint xmlSchemaIdentityConstraint in xmlSchemaElement.Constraints)
                    {
                        // Evaluate the foreign keys in the data model.
                        if (xmlSchemaIdentityConstraint is XmlSchemaKeyref)
                        {
                            // This object can be used as a foreign key constraint and, optionally, can be used to describe a
                            // parent/child relationship.
                            XmlSchemaKeyref xmlSchemaKeyref = xmlSchemaIdentityConstraint as XmlSchemaKeyref;

                            // This creates a foreign key.
                            ForeignKeyConstraintSchema foreignKeyConstraintSchema = new ForeignKeyConstraintSchema(this, xmlSchemaIdentityConstraint as XmlSchemaKeyref);

                            // Foreign constraint schemas are always added to the list of constraints on a table.  They can also
                            // conditionally become the source for a relationship between two tables.
                            foreignKeyConstraintSchema.Table.Add(foreignKeyConstraintSchema);

                            // Unless specifically instructed to supress the relation, it will be created add added to both the
                            // parent and child tables as well as the data model.
                            XmlAttribute isConstraintOnlyAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaIdentityConstraint, QualifiedName.ConstraintOnly);
                            if (isConstraintOnlyAttribute == null || !Convert.ToBoolean(isConstraintOnlyAttribute.Value))
                            {
                                RelationSchema relationSchema = new RelationSchema(this, xmlSchemaKeyref);
                                relationSchema.ParentTable.ChildRelations.Add(relationSchema.Name, relationSchema);
                                relationSchema.ChildTable.ParentRelations.Add(relationSchema.Name, relationSchema);
                                this.Relations.Add(relationSchema.Name, relationSchema);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Initializes the column from an XmlSchemaElement or XmlSchemaAttribute.
        /// </summary>
        /// <param name="xmlSchemaAnnotated">An XmlSchema object containing the attributes of the column.</param>
        private void Initialize(XmlSchemaAnnotated xmlSchemaAnnotated)
        {
            // Extract the column properties from an XmlSchemaElement.
            if (xmlSchemaAnnotated is XmlSchemaElement)
            {
                // This element is used to describe the column.
                XmlSchemaElement xmlSchemaElement = xmlSchemaAnnotated as XmlSchemaElement;

                // This information is taken directly from the known XmlSchema attributes.  The rest of the information about the
                // column needs to be extracted using unhandled attributes and element facets.
                this.name       = xmlSchemaElement.Name;
                this.isNullable = xmlSchemaElement.MinOccurs == 0.0m;

                // Extract the string that contains the type information from the 'DataType' custom attribute.  This is a
                // Microsoft extension to the XML Schema definition.
                XmlAttribute dataTypeAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaElement, QualifiedName.DataType);
                if (dataTypeAttribute != null)
                {
                    // The type information is stored as a string.  This will rip apart the string to get the type,
                    // assembly, version, etc. information that can be used to access the type through reflection.
                    string   typeName = dataTypeAttribute.Value;
                    string[] parts    = typeName.Split(',');

                    // There's no a lot of fancy parsing going on here.  If it doesn't match the expected format, then
                    // reject the type.
                    if (parts.Length != 5)
                    {
                        throw new Exception(string.Format("Can't analyze the data type found on line {0}, {1}", xmlSchemaElement.LineNumber, typeName));
                    }

                    // This will load the assembly into memory and use reflection to get the data type that was specified
                    // in the XML file as a string.
                    string   assemblyFullName = string.Format("{0},{1},{2},{3}", parts[1], parts[2], parts[3], parts[4]);
                    Assembly assembly         = Assembly.Load(assemblyFullName);
                    if (assembly == null)
                    {
                        throw new Exception(string.Format("Unable to load the type {0} from assembly {1}", parts[0], assemblyFullName));
                    }
                    this.dataType = assembly.GetType(parts[0]);
                    if (this.dataType == null)
                    {
                        throw new Exception(string.Format("Unable to load the type {0} from assembly {1}", parts[0], assemblyFullName));
                    }
                }
                else
                {
                    // This will extract the simple data type and the maximum field length from the facets associated with the element.
                    if (xmlSchemaElement.ElementSchemaType is XmlSchemaSimpleType)
                    {
                        XmlSchemaSimpleType xmlSchemaSimpleType = xmlSchemaElement.ElementSchemaType as XmlSchemaSimpleType;
                        this.dataType = xmlSchemaSimpleType.Datatype.ValueType;
                        if (xmlSchemaSimpleType.Content is XmlSchemaSimpleTypeRestriction)
                        {
                            XmlSchemaSimpleTypeRestriction xmlSchemaSimpleTypeRestriction = xmlSchemaSimpleType.Content as XmlSchemaSimpleTypeRestriction;
                            foreach (XmlSchemaFacet xmlSchemaFacet in xmlSchemaSimpleTypeRestriction.Facets)
                            {
                                if (xmlSchemaFacet is XmlSchemaMaxLengthFacet)
                                {
                                    XmlSchemaMaxLengthFacet xmlSchemaMaxLengthFacet = xmlSchemaFacet as XmlSchemaMaxLengthFacet;
                                    this.maximumLength = Convert.ToInt32(xmlSchemaMaxLengthFacet.Value);
                                }
                            }
                        }
                    }
                }

                // The defalt value can only be evaluated after the data type has been determined.  Otherwise, there's no way to
                // know to which data type the default value is converted.
                this.defaultValue = DataModelSchema.ConvertValue(this.dataType, xmlSchemaElement.DefaultValue);
            }

            // Extract the column properties from an Attribute.
            if (xmlSchemaAnnotated is XmlSchemaAttribute)
            {
                // This attribute describes the column.
                XmlSchemaAttribute xmlSchemaAttribute = xmlSchemaAnnotated as XmlSchemaAttribute;

                // This information is taken directly from the known XmlSchema attributes.  The rest of the information about the
                // column needs to be extracted using unhandled attributes and element facets.
                this.name         = xmlSchemaAttribute.Name;
                this.dataType     = xmlSchemaAttribute.AttributeSchemaType.Datatype.ValueType;
                this.defaultValue = DataModelSchema.ConvertValue(this.dataType, xmlSchemaAttribute.DefaultValue);
            }

            // Determine the IsEncryptedColumn property.
            XmlAttribute isColumnEncrytedAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaAnnotated,
                                                                                        QualifiedName.IsEncrypted);

            this.isEncrypted = isColumnEncrytedAttribute == null ? false : Convert.ToBoolean(isColumnEncrytedAttribute.Value);

            // Determine the IsIdentityColumn property.
            XmlAttribute autoIncrementAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaAnnotated,
                                                                                     QualifiedName.AutoIncrement);

            this.isAutoIncrement = autoIncrementAttribute == null ? false : Convert.ToBoolean(autoIncrementAttribute.Value);

            // Determine the IsPersistent property.
            XmlAttribute isColumnPersistentAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaAnnotated,
                                                                                          QualifiedName.IsPersistent);

            this.isPersistent = isColumnPersistentAttribute == null ? true : Convert.ToBoolean(isColumnPersistentAttribute.Value);

            // Determine the AutoIncrementSeed property.
            XmlAttribute autoIncrementSeedAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaAnnotated,
                                                                                         QualifiedName.AutoIncrementSeed);

            this.autoIncrementSeed = autoIncrementSeedAttribute == null ? 0 : Convert.ToInt32(autoIncrementSeedAttribute.Value);

            // Determine the AutoIncrementStop property
            XmlAttribute autoIncrementStepAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaAnnotated,
                                                                                         QualifiedName.AutoIncrementStep);

            this.autoIncrementStep = autoIncrementStepAttribute == null ? 0 : Convert.ToInt32(autoIncrementStepAttribute.Value);
        }