/// <summary> /// Indicates whether a column is or is descended from an identity column. /// </summary> /// <param name="elementTable">The table description.</param> /// <param name="columnSchema">The column description.</param> /// <returns>true of the column is or is descended from an identity column.</returns> public bool IsExternalIdColumn(ColumnSchema columnSchema) { if (IsPrimaryKeyColumn(columnSchema) && this.HasExternalIdColumn) { return(true); } foreach (TableSchema parentTable in this.GetParentTables) { if (parentTable.IsExternalIdColumn(columnSchema)) { return(true); } } // At this point, the object hierarchy has been searched and no identity column was found. return(false); }
/// <summary> /// Generate the keys on a table. /// </summary> /// <param name="streamWriter">The file to which the DDL is written.</param> /// <param name="tableSchema">The schema description of the table.</param> private static void GenerateKeys(StreamWriter streamWriter, TableSchema tableSchema) { // This architecture foregoes the 'query' mechanism for finding records in favor of a more direct record identifier. // Every table has an implicit key created on the row identifier used to quickly find any given record. streamWriter.WriteLine(" /* Unique Constraints */"); streamWriter.WriteLine(" alter table \"{0}\" with nocheck add ", tableSchema.Name); // This will add any additional keys to the table. for (int keyIndex = 0; keyIndex < tableSchema.Keys.Count; keyIndex++) { ConstraintSchema constraintSchema = tableSchema.Keys[keyIndex]; if (constraintSchema.IsNullable) { continue; } if (constraintSchema.IsPrimaryKey) { streamWriter.WriteLine(" constraint \"{0}\" primary key clustered", constraintSchema.Name); } else { streamWriter.WriteLine(" constraint \"{0}\" unique", constraintSchema.Name); } streamWriter.WriteLine(" ("); ColumnSchema[] keyFields = constraintSchema.Fields; for (int columnIndex = 0; columnIndex < keyFields.Length; columnIndex++) { ColumnSchema columnSchema = keyFields[columnIndex]; streamWriter.Write(" \"{0}\"", columnSchema.Name); streamWriter.WriteLine(columnIndex == keyFields.Length - 1 ? "" : ","); } streamWriter.Write(" ) on \"PRIMARY\" "); // End with a comment if there are more foreign constraints comming. streamWriter.WriteLine(keyIndex < tableSchema.Keys.Count - 1 ? "," : ""); } streamWriter.WriteLine(""); // Roll the transaction back if the indices can't be created. streamWriter.WriteLine(""); }
/// <summary> /// Compares a ColumnSchema to another object. /// </summary> /// <param name="obj">The object to be compared.</param> /// <returns>-1 if this object is less than the specified object, -1 if it is greater and 0 if they are equal.</returns> public int CompareTo(object obj) { // Compare the object to an XmlQualifiedName. if (obj is XmlQualifiedName) { XmlQualifiedName xmlQualifiedName = obj as XmlQualifiedName; int compare = this.QualifiedName.Namespace.CompareTo(xmlQualifiedName.Namespace); return(compare == 0 ? this.QualifiedName.Name.CompareTo(xmlQualifiedName.Name) : compare); } // Compare the object to another ColumnSchema. if (obj is ColumnSchema) { ColumnSchema columnSchema = obj as ColumnSchema; int compare = this.QualifiedName.Namespace.CompareTo(columnSchema.QualifiedName.Namespace); return(compare == 0 ? this.QualifiedName.Name.CompareTo(columnSchema.Name) : compare); } // No other comparisons are recognized. throw new Exception(string.Format("The method or operation is not implemented for a {0} type.", obj.GetType())); }
/// <summary> /// Generates the foreign keys on a table. /// </summary> /// <param name="streamWriter">The file to which the DDL is written.</param> /// <param name="tableSchema">The schema description of the table.</param> private static void GenerateForeignKeys(StreamWriter streamWriter, TableSchema tableSchema) { // This will generate the foreign keys for the table. if (tableSchema.ParentKeyrefs.Count != 0) { streamWriter.WriteLine(" /* Foreign Keys */"); streamWriter.WriteLine(" alter table \"{0}\" add ", tableSchema.Name); for (int foreignKeyIndex = 0; foreignKeyIndex < tableSchema.ParentKeyrefs.Count; foreignKeyIndex++) { KeyrefSchema keyrefSchema = tableSchema.ParentKeyrefs[foreignKeyIndex] as KeyrefSchema; streamWriter.WriteLine(" constraint \"{0}\" foreign key ", keyrefSchema.Name); streamWriter.WriteLine(" ("); // Generate the child field names. ColumnSchema[] childFields = keyrefSchema.Fields; for (int columnIndex = 0; columnIndex < childFields.Length; columnIndex++) { ColumnSchema columnSchema = childFields[columnIndex]; streamWriter.Write(" \"{0}\"", columnSchema.Name); streamWriter.WriteLine(columnIndex == childFields.Length - 1 ? "" : ","); } // Generate the parent 'refer' selector and field names. streamWriter.WriteLine(" ) references \"{0}\" (", keyrefSchema.Refer.Selector.Name); ColumnSchema[] parentFields = keyrefSchema.Refer.Fields; for (int columnIndex = 0; columnIndex < childFields.Length; columnIndex++) { ColumnSchema columnSchema = parentFields[columnIndex]; streamWriter.Write(" \"{0}\"", columnSchema.Name); streamWriter.WriteLine(columnIndex == childFields.Length - 1 ? "" : ","); } // End with a comment if there are more foreign constraints comming. streamWriter.WriteLine(foreignKeyIndex < tableSchema.ParentKeyrefs.Count - 1 ? " ),": " )"); } // Roll the transaction back on errors. streamWriter.WriteLine(""); } }
/// <summary> /// Indicates that a column is an identity column. /// </summary> /// <param name="columnSchema">The description of a column.</param> /// <returns>true if the column has an internally generated identifier.</returns> public bool IsIdentityColumn(ColumnSchema columnSchema) { if (columnSchema.IsAutoIncrement) { return(true); } // See if the column may is part of an identity column in the base table. TableSchema baseTable = this.BaseTable; if (baseTable != null) { // See if the column is the identity column in the base table. if (baseTable.IsIdentityColumn(columnSchema)) { return(true); } // If the column is part of the primary key, then it's possible that the column is an identity column through a // primary key relation. ConstraintSchema keySchema = this.PrimaryKey; if (keySchema != null && keySchema.Fields.Length == 1 && keySchema.Fields[0] == columnSchema) { // See if the column is related to an identity column through the primary index. ConstraintSchema baseKeySchema = baseTable.PrimaryKey; KeyrefSchema baseKeyRefSchema = this.FindForeignKey(new ColumnSchema[] { columnSchema }); if (baseKeyRefSchema != null && baseKeyRefSchema.Refer == baseKeySchema) { if (baseKeySchema.Fields.Length == 1) { ColumnSchema baseColumnSchema = baseTable.Columns[baseKeySchema.Fields[0].QualifiedName]; return(baseTable.IsExternalIdColumn(baseColumnSchema)); } } } } return(false); }
/// <summary> /// Generates a property to get or set the column data of a row. /// </summary> /// <param name="tableSchema">The table to which this row belongs.</param> /// <param name="columnSchema">The nullable column.</param> public RowColumnProperty(TableSchema tableSchema, ColumnSchema columnSchema) { // /// <summary> // /// Gets or sets the data in the DepartmentId column. // /// </summary> // public int DepartmentId // { // get // { // return ((int)(this[this.tableDepartment.DepartmentIdColumn])); // } // set // { // this[this.tableDepartment.DepartmentIdColumn] = value; // } // } Type columnType = columnSchema.DataType; this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(string.Format("Gets or sets the data in the {0} column.", columnSchema.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.Type = new CodeTypeReference(columnType); this.Name = columnSchema.Name; if (columnSchema.MinOccurs == 0) { CodeTryCatchFinallyStatement tryCatchBlock = new CodeTryCatchFinallyStatement(); tryCatchBlock.TryStatements.Add(new CodeMethodReturnStatement(new CodeCastExpression(columnType, new CodeArrayIndexerExpression(new CodeThisReferenceExpression(), new CodeExpression[] { new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), string.Format("table{0}", tableSchema.Name)), string.Format("{0}Column", columnSchema.Name)) })))); CodeStatement[] catchStatements = new CodeStatement[] { new CodeThrowExceptionStatement(new CodeObjectCreateExpression(new CodeTypeReference("StrongTypingException"), new CodeExpression[] { new CodePrimitiveExpression("Cannot get value because it is DBNull."), new CodeArgumentReferenceExpression("e") })) }; tryCatchBlock.CatchClauses.Add(new CodeCatchClause("e", new CodeTypeReference("InvalidCastException"), catchStatements)); this.GetStatements.Add(tryCatchBlock); } else { this.GetStatements.Add(new CodeMethodReturnStatement(new CodeCastExpression(columnType, new CodeArrayIndexerExpression(new CodeThisReferenceExpression(), new CodeExpression[] { new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), string.Format("table{0}", tableSchema.Name)), string.Format("{0}Column", columnSchema.Name)) })))); } this.SetStatements.Add(new CodeAssignStatement(new CodeArrayIndexerExpression(new CodeThisReferenceExpression(), new CodeExpression[] { new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), string.Format("table{0}", tableSchema.Name)), string.Format("{0}Column", columnSchema.Name)) }), new CodePropertySetValueReferenceExpression())); }
/// <summary> /// Generates a property to get a parent row. /// </summary> /// <param name="keyrefSchema">The foreign key that references the parent table.</param> public TableColumnProperty(TableSchema tableSchema, ColumnSchema columnSchema) { // Construct the type names for the table and rows within the table. string rowTypeName = string.Format("{0}Row", tableSchema.Name); // /// <summary> // /// Gets the DepartmentId column of the Department table. // /// </summary> // public Column DepartmentIdColumn // { // get // { // return this.columnDepartmentId; // } // } this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(string.Format("Gets the {0} column of the {1} table.", columnSchema.Name, tableSchema.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.Type = new CodeTypeReference("Column"); this.Name = string.Format("{0}Column", columnSchema.Name); this.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), string.Format("column{0}", columnSchema.Name)))); }
/// <summary> /// Tests to see if a given column is part of the primary key. /// </summary> /// <param name="elementTable">The table schema to test.</param> /// <param name="columnSchema">The column schema to test.</param> /// <returns>True if the column belongs to the primary key of the table.</returns> public bool IsPrimaryKeyColumn(ColumnSchema columnSchema) { // Find the primary key of the requested table. ConstraintSchema keySchema = PrimaryKey; // Test each field in the key to see if the selector matches the given column name. foreach (ColumnSchema fieldSchema in keySchema.Fields) { if (fieldSchema == columnSchema) { return(true); } } // If there is a base class, then see if this column is part of the base class primary key. if (this.BaseTable != null) { return(this.BaseTable.IsPrimaryKeyColumn(columnSchema)); } // At this point, the column doesn not belong to any of the primary keys in the hiearchy. return(false); }
/// <summary> /// Creates the CodeDOM for a method to insert a record into a table using transacted logic. /// </summary> /// <param name="tableSchema">A description of the table.</param> public Insert(TableSchema tableSchema) : base(tableSchema) { // /// <summary>Inserts a Department record.</summary> // /// <param name="departmentId">The value for the DepartmentId column.</param> // /// <param name="description">The value for the Description column.</param> // /// <param name="externalId0">The value for the ExternalId0 column.</param> // /// <param name="externalId1">The value for the ExternalId1 column.</param> // /// <param name="name">The value for the Name column.</param> // /// <param name="typeCode">The value for the TypeCode column.</param> // public static void Insert(out int departmentId, object description, object externalId0, object externalId1, string name, object typeCode, out long rowVersion) // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(string.Format("Inserts a {0} record.", this.TableSchema.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); foreach (ColumnSchema columnSchema in this.TableSchema.Columns) { if (!this.TableSchema.IsPrimaryKeyColumn(columnSchema) || columnSchema.DeclaringType == this.TableSchema.TypeSchema) { this.Comments.Add(new CodeCommentStatement(string.Format(@"<param name=""{0}"">The value for the {1} column.</param>", Generate.CamelCase(columnSchema.Name), columnSchema.Name), true)); } } this.Comments.Add(new CodeCommentStatement(@"<param name=""rowVersion"">Used for Optimistic Concurrency Checking.</param>", true)); this.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static; this.Name = "Insert"; foreach (ColumnSchema columnSchema in this.TableSchema.Columns) { if (!this.TableSchema.IsPrimaryKeyColumn(columnSchema) || columnSchema.DeclaringType == this.TableSchema.TypeSchema) { Type typeColumn = columnSchema.DataType; Type typeVariable = columnSchema.MinOccurs == 0 || columnSchema.DefaultValue != null ? typeof(object) : typeColumn; CodeParameterDeclarationExpression parameter = new CodeParameterDeclarationExpression(typeVariable, Generate.CamelCase(columnSchema.Name)); if (this.TableSchema.IsAutogeneratedColumn(columnSchema)) { parameter.Direction = FieldDirection.Out; } this.Parameters.Add(parameter); } } CodeParameterDeclarationExpression rowVersionParameter = new CodeParameterDeclarationExpression(typeof(long), "rowVersion"); rowVersionParameter.Direction = FieldDirection.Out; this.Parameters.Add(rowVersionParameter); // // This method is part of a larger transaction. Instead of passing the transaction and the resource managers down // // through several layers of methods, they are acccessed as ambient properties of the Transaction class. // Transaction transaction = Transaction.Current; // AdoResourceManager adoResourceManager = ((AdoResourceManager)(transaction["ADO Data Model"])); // SqlResourceManager sqlResourceManager = ((SqlResourceManager)(transaction["SQL Data Model"])); this.Statements.Add(new CodeCommentStatement("This method is part of a larger transaction. Instead of passing the transaction and the resource managers down")); this.Statements.Add(new CodeCommentStatement("through several layers of methods, they are acccessed as ambient properties of the Transaction class.")); this.Statements.Add(new CodeVariableDeclarationStatement("Transaction", "transaction", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("Transaction"), "Current"))); this.Statements.Add(new CodeVariableDeclarationStatement("AdoResourceManager", "adoResourceManager", new CodeCastExpression("AdoResourceManager", new CodeIndexerExpression(new CodeVariableReferenceExpression("transaction"), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.TableSchema.Name), "VolatileResource"))))); this.Statements.Add(new CodeVariableDeclarationStatement("SqlResourceManager", "sqlResourceManager", new CodeCastExpression("SqlResourceManager", new CodeIndexerExpression(new CodeVariableReferenceExpression("transaction"), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.TableSchema.Name), "DurableResource"))))); // // Lock the parent Race record for the duration of the transaction. // if (raceCode != null) // { // ServerDataModel.RaceRow raceRow = ServerDataModel.Race.FindByRaceCode(((int)raceCode)); // raceRow.ReaderWriterLock.AcquireReaderLock(System.Threading.Timeout.Infinite); // adoResourceManager.Add(raceRow.ReaderWriterLock); // } foreach (KeyrefSchema parentKey in this.TableSchema.ParentKeyrefs) { if (!this.TableSchema.IsBaseKeyref(parentKey)) { TableSchema parentTable = parentKey.Refer.Selector; this.Statements.Add(new CodeCommentStatement(string.Format("Lock the parent {0} record for the duration of the transaction.", parentTable.Name))); CodeExpression lockConditions = null; foreach (ColumnSchema columnSchema in parentKey.Fields) { if (columnSchema.MinOccurs == 0) { lockConditions = lockConditions == null ? new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(Generate.CamelCase(columnSchema.Name)), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)) : new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(Generate.CamelCase(columnSchema.Name)), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), CodeBinaryOperatorType.BitwiseAnd, lockConditions); } } List <CodeStatement> lockParentRow = new List <CodeStatement>(); string parentRowName = string.Format("{0}Row", Generate.CamelCase(parentTable.Name)); string methodName = "FindBy"; List <CodeExpression> keyList = new List <CodeExpression>(); for (int fieldIndex = 0; fieldIndex < parentKey.Fields.Length; fieldIndex++) { ColumnSchema parentColumn = parentKey.Refer.Fields[fieldIndex]; ColumnSchema childColumn = parentKey.Fields[fieldIndex]; methodName += parentColumn.Name; keyList.Add(childColumn.MinOccurs == 0 ? (CodeExpression) new CodeCastExpression(childColumn.DataType, new CodeArgumentReferenceExpression(Generate.CamelCase(childColumn.Name))) : (CodeExpression) new CodeArgumentReferenceExpression(Generate.CamelCase(childColumn.Name))); } lockParentRow.Add(new CodeVariableDeclarationStatement(new CodeTypeReference(string.Format("{0}.{1}Row", this.ServerSchema.Name, parentTable.Name)), parentRowName, new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, parentTable.Name)), methodName, keyList.ToArray()))); lockParentRow.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(parentRowName), "ReaderWriterLock"), "AcquireReaderLock", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(System.Threading.Timeout)), "Infinite")))); lockParentRow.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("adoResourceManager"), "Add", new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(parentRowName), "ReaderWriterLock")))); if (lockConditions == null) { this.Statements.AddRange(lockParentRow.ToArray()); } else { this.Statements.Add(new CodeConditionStatement(lockConditions, lockParentRow.ToArray())); } } } // // Apply Fixed Values // int objectTypeCode = 12; bool isFixedCommentEmitted = false; foreach (ColumnSchema columnSchema in this.TableSchema.Columns) { if (columnSchema.FixedValue != null) { if (!isFixedCommentEmitted) { this.Statements.Add(new CodeCommentStatement("Apply Fixed Values")); isFixedCommentEmitted = true; } Type typeVariable = columnSchema.MinOccurs == 0 ? typeof(object) : columnSchema.DataType; this.Statements.Add(new CodeVariableDeclarationStatement(typeVariable, Generate.CamelCase(columnSchema.Name), Generate.PrimativeExpression(columnSchema.FixedValue))); } } // // Apply Defaults // if ((description == null)) // { // description = System.DBNull.Value; // } // if ((externalId0 == null)) // { // externalId0 = System.DBNull.Value; // } // if ((externalId1 == null)) // { // externalId1 = System.DBNull.Value; // } // if ((typeCode == null)) // { // typeCode = "Department"; // } bool isDefaultCommentEmitted = false; foreach (ColumnSchema columnSchema in this.TableSchema.Columns) { if (columnSchema.DefaultValue != null) { if (!isDefaultCommentEmitted) { this.Statements.Add(new CodeCommentStatement("Apply Defaults")); isDefaultCommentEmitted = true; } Type typeVariable = columnSchema.MinOccurs == 0 ? typeof(object) : columnSchema.DataType; this.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeArgumentReferenceExpression(Generate.CamelCase(columnSchema.Name)), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null)), new CodeStatement[] { new CodeAssignStatement(new CodeArgumentReferenceExpression(Generate.CamelCase(columnSchema.Name)), Generate.PrimativeExpression(columnSchema.DefaultValue)) })); } } bool isCommandDeclared = false; foreach (TableSchema familyTable in this.TableSchema.TableHierarchy) { // To reduce the frequency of deadlocking, the tables are always locked in alphabetical order. This section collects // all the table locks that are used for this operation and organizes them in a list that is used to generate the // locking and releasing statements below. List <TableSchema> parentList = new List <TableSchema>(); foreach (KeyrefSchema parentKeyref in familyTable.ParentKeyrefs) { parentList.Add(parentKeyref.Refer.Selector); } parentList.Sort(); // // Add the Object record to the ADO data model. // ServerDataModel.ObjectRow objectRow = ServerDataModel.Object.NewObjectRow(); // objectRow.ReaderWriterLock.AcquireWriterLock(System.Threading.Timeout.Infinite); // adoResourceManager.Add(objectRow.ReaderWriterLock); // adoResourceManager.Add(objectRow); // try // { // ServerDataModel.Object.ReaderWriterLock.AcquireWriterLock(System.Threading.Timeout.Infinite); // ServerDataModel.Object.ReaderWriterLock.AcquireReaderLock(System.Threading.Timeout.Infinite); // objectRow[ServerDataModel.Object.DescriptionColumn] = description; // objectRow[ServerDataModel.Object.ExternalId0Column] = externalId0; // objectRow[ServerDataModel.Object.ExternalId1Column] = externalId1; // objectRow[ServerDataModel.Object.NameColumn] = name; // objectRow[ServerDataModel.Object.TypeCodeColumn] = typeCode; // objectRow[ServerDataModel.Object.RowVersionColumn] = ServerDataModel.IncrementRowVersion(); // } // finally // { // ServerDataModel.Object.ReaderWriterLock.ReleaseWriterLock(); // ServerDataModel.Object.ReaderWriterLock.ReleaseReaderLock(); // } string rowName = string.Format("{0}Row", Generate.CamelCase(familyTable.Name)); this.Statements.Add(new CodeCommentStatement(string.Format("Add the {0} record to the ADO data model.", familyTable.Name))); this.Statements.Add(new CodeVariableDeclarationStatement(string.Format("{0}.{1}Row", this.ServerSchema.Name, familyTable.Name), rowName, new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.ServerSchema.Name), familyTable.Name), string.Format("New{0}Row", familyTable.Name)))); this.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(rowName), "ReaderWriterLock"), "AcquireWriterLock", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(System.Threading.Timeout)), "Infinite"))); this.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("adoResourceManager"), "Add", new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(rowName), "ReaderWriterLock"))); this.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("adoResourceManager"), "Add", new CodeVariableReferenceExpression(rowName))); CodeTryCatchFinallyStatement tryFinallyStatement = new CodeTryCatchFinallyStatement(); tryFinallyStatement.TryStatements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression(rowName), "BeginEdit")); foreach (ColumnSchema columnSchema in familyTable.Columns) { if (columnSchema.DeclaringType == familyTable.TypeSchema) { if (columnSchema.IsAutoIncrement) { continue; } if (familyTable.IsInheritedKey(columnSchema)) { TableSchema baseTable = familyTable.BaseTable; int keyIndex = Array.IndexOf(familyTable.PrimaryKey.Fields, columnSchema); tryFinallyStatement.TryStatements.Add(new CodeAssignStatement(new CodeIndexerExpression(new CodeVariableReferenceExpression(rowName), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, familyTable.Name)), string.Format("{0}Column", columnSchema.Name))), new CodeIndexerExpression(new CodeVariableReferenceExpression(string.Format("{0}Row", Generate.CamelCase(baseTable.Name))), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, baseTable.Name)), string.Format("{0}Column", baseTable.PrimaryKey.Fields[keyIndex].Name))) )); } else { tryFinallyStatement.TryStatements.Add(new CodeAssignStatement(new CodeIndexerExpression(new CodeVariableReferenceExpression(rowName), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, familyTable.Name)), string.Format("{0}Column", columnSchema.Name))), new CodeArgumentReferenceExpression(Generate.CamelCase(columnSchema.Name)))); } } } tryFinallyStatement.TryStatements.Add(new CodeAssignStatement(new CodeIndexerExpression(new CodeVariableReferenceExpression(rowName), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, familyTable.Name)), "RowVersionColumn")), new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(this.ServerSchema.Name), "IncrementRowVersion"))); tryFinallyStatement.TryStatements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, familyTable.Name)), string.Format("Add{0}Row", familyTable.Name), new CodeVariableReferenceExpression(rowName))); tryFinallyStatement.FinallyStatements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression(rowName), "EndEdit")); this.Statements.Add(tryFinallyStatement); // // Add the Object record to the SQL data model. // System.Data.SqlClient.SqlCommand sqlCommand = new SqlCommand("insert \"Object\" (\"Description\",\"ExternalId0\",\"ExternalId1\",\"Name\",\"ObjectId\",\"Typ" + // "eCode\",\"RowVersion\") values (@description,@externalId0,@externalId1,@name,@objec" + // "tId,@typeCode,@rowVersion)", sqlResourceManager.SqlConnection); // sqlCommand.Parameters.Add(new SqlParameter("@description", SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, description)); // sqlCommand.Parameters.Add(new SqlParameter("@externalId0", SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, externalId0)); // sqlCommand.Parameters.Add(new SqlParameter("@externalId1", SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, externalId1)); // sqlCommand.Parameters.Add(new SqlParameter("@name", SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, name)); // sqlCommand.Parameters.Add(new SqlParameter("@objectId", SqlDbType.Int, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, objectRow[ServerDataModel.Object.ObjectIdColumn])); // sqlCommand.Parameters.Add(new SqlParameter("@typeCode", SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, typeCode)); // sqlCommand.Parameters.Add(new SqlParameter("@rowVersion", SqlDbType.BigInt, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, objectRow[ServerDataModel.Object.RowVersionColumn])); // sqlCommand.ExecuteNonQuery(); if (this.TableSchema.IsPersistent) { this.Statements.Add(new CodeCommentStatement(string.Format("Add the {0} record to the SQL data model.", familyTable.Name))); string columnList = string.Empty; string variableList = string.Empty; foreach (ColumnSchema columnSchema in familyTable.Columns) { if (columnSchema.IsPersistent && columnSchema.DeclaringType == familyTable.TypeSchema) { columnList += string.Format("\"{0}\",", columnSchema.Name); variableList += string.Format("@{0},", Generate.CamelCase(columnSchema.Name)); } } columnList += "\"RowVersion\""; variableList += "@rowVersion"; string insertCommandText = string.Format("insert \"{0}\" ({1}) values ({2})", familyTable.Name, columnList, variableList); if (isCommandDeclared) { this.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("sqlCommand"), new CodeObjectCreateExpression("SqlCommand", new CodePrimitiveExpression(insertCommandText), new CodeFieldReferenceExpression(new CodeArgumentReferenceExpression("sqlResourceManager"), "SqlConnection")))); } else { isCommandDeclared = true; this.Statements.Add(new CodeVariableDeclarationStatement(typeof(System.Data.SqlClient.SqlCommand), "sqlCommand", new CodeObjectCreateExpression("SqlCommand", new CodePrimitiveExpression(insertCommandText), new CodeFieldReferenceExpression(new CodeArgumentReferenceExpression("sqlResourceManager"), "SqlConnection")))); } foreach (ColumnSchema columnSchema in this.TableSchema.Columns) { if (columnSchema.IsPersistent && columnSchema.DeclaringType == familyTable.TypeSchema) { string variableName = Generate.CamelCase(columnSchema.Name); if (familyTable.IsAutogeneratedColumn(columnSchema)) { CodeExpression codeExpression = new CodeIndexerExpression(new CodeVariableReferenceExpression(string.Format("{0}Row", Generate.CamelCase(familyTable.Name))), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, familyTable.Name)), string.Format("{0}Column", columnSchema.Name))); this.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("sqlCommand"), "Parameters"), "Add", new CodeExpression[] { new CodeObjectCreateExpression("SqlParameter", new CodeExpression[] { new CodePrimitiveExpression(string.Format("@{0}", variableName)), TypeConverter.Convert(columnSchema.DataType), new CodePrimitiveExpression(0), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("ParameterDirection"), "Input"), new CodePrimitiveExpression(false), new CodePrimitiveExpression(0), new CodePrimitiveExpression(0), new CodePrimitiveExpression(null), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("DataRowVersion"), "Current"), codeExpression }) })); } else { this.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("sqlCommand"), "Parameters"), "Add", new CodeExpression[] { new CodeObjectCreateExpression("SqlParameter", new CodeExpression[] { new CodePrimitiveExpression(string.Format("@{0}", variableName)), TypeConverter.Convert(columnSchema.DataType), new CodePrimitiveExpression(0), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("ParameterDirection"), "Input"), new CodePrimitiveExpression(false), new CodePrimitiveExpression(0), new CodePrimitiveExpression(0), new CodePrimitiveExpression(null), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("DataRowVersion"), "Current"), new CodeArgumentReferenceExpression(variableName) }) })); } } } this.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("sqlCommand"), "Parameters"), "Add", new CodeObjectCreateExpression("SqlParameter", new CodePrimitiveExpression("@rowVersion"), new CodeTypeReferenceExpression("SqlDbType.BigInt"), new CodePrimitiveExpression(0), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("ParameterDirection"), "Input"), new CodePrimitiveExpression(false), new CodePrimitiveExpression(0), new CodePrimitiveExpression(0), new CodePrimitiveExpression(null), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("DataRowVersion"), "Current"), new CodeIndexerExpression(new CodeVariableReferenceExpression(string.Format("{0}Row", Generate.CamelCase(familyTable.Name))), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, familyTable.Name)), "RowVersionColumn"))))); this.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("sqlCommand"), "ExecuteNonQuery")); } } // // Autogenerated values are returned to the caller. // departmentId = (int)departmentRow[ServerDataModel.Department.DepartmentIdColumn]; // rowVersion = (long)departmentRow[ServerDataModel.Department.RowVersionColumn]; this.Statements.Add(new CodeCommentStatement("Autogenerated values are returned to the caller.")); foreach (ColumnSchema columnSchema in this.TableSchema.Columns) { if (this.TableSchema.IsAutogeneratedColumn(columnSchema) && columnSchema.DeclaringType == this.TableSchema.TypeSchema) { this.Statements.Add(new CodeAssignStatement(new CodeArgumentReferenceExpression(Generate.CamelCase(columnSchema.Name)), new CodeCastExpression(columnSchema.DataType, new CodeIndexerExpression(new CodeVariableReferenceExpression(string.Format("{0}Row", Generate.CamelCase(this.TableSchema.Name))), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, this.TableSchema.Name)), string.Format("{0}Column", columnSchema.Name)))))); } } this.Statements.Add(new CodeAssignStatement(new CodeArgumentReferenceExpression("rowVersion"), new CodeCastExpression(typeof(long), new CodeIndexerExpression(new CodeVariableReferenceExpression(string.Format("{0}Row", Generate.CamelCase(this.TableSchema.Name))), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(string.Format("{0}.{1}", this.ServerSchema.Name, this.TableSchema.Name)), "RowVersionColumn"))))); }
public bool TryGetValue(string key, out ColumnSchema value) { return(this.columnList.TryGetValue(key, out value)); }
public void Add(ColumnSchema columnSchema) { this.columnList.Add(columnSchema.Name, columnSchema); }
internal void GetColumns(ColumnSchemaCollection columnSchemaCollection) { // The ComplexContent is mutually exclusive of the Particle. That is, if there is no particle defined for this comlex // type then it must have a comlex content description. Comlex content extends a base class. if (this.xmlSchemaComplexType == null) { // The Comlex Content describes an extension of a base class. if (this.xmlSchemaComplexType.ContentModel is XmlSchemaComplexContent) { // Strongly type the XmlSchemaContent. XmlSchemaComplexContent xmlSchemaComplexContent = xmlSchemaComplexType.ContentModel as XmlSchemaComplexContent; // A complex content can be derived by extension (adding columns) or restriction (removing columns). This // section will look for the extensions to the base class. if (xmlSchemaComplexContent.Content is XmlSchemaComplexContentExtension) { // The Complex Content Extension describes a base class and the additional columns that make up a derived // class. This section will recursively collect the columns from the base class and then parse out the // extra columns in-line. XmlSchemaComplexContentExtension xmlSchemaComplexContentExtension = xmlSchemaComplexContent.Content as XmlSchemaComplexContentExtension; // This will recursively read the columns from the base classes. TypeSchema baseType = this.Schema.GetTypeSchema(xmlSchemaComplexContentExtension.BaseTypeName); baseType.GetColumns(columnSchemaCollection); // The additional columns for this inherited table are found on the in-line in the <sequence> node that follows // the <extension> node. if (xmlSchemaComplexContentExtension.Particle is XmlSchemaSequence) { // Strongly type the XmlSchemaSequence XmlSchemaSequence xmlSchemaSequence = xmlSchemaComplexContentExtension.Particle as XmlSchemaSequence; // Read through the sequence and replace any column from an inherited class with the column in the // derived class. Also note that the columns are added in alphabetical order to give some amount of // predictability to the way the parameter lists are constructed when there are several layers of // inheritance. foreach (XmlSchemaObject xmlSchemaObject in xmlSchemaSequence.Items) { ColumnSchema columnSchema = new ColumnSchema(this.Schema, xmlSchemaObject); if (columnSchemaCollection.ContainsKey(columnSchema.Name)) { columnSchemaCollection.Remove(columnSchema.Name); } columnSchemaCollection.Add(columnSchema); } } // The Complex Content can also contain attributes that describe columns. foreach (XmlSchemaAttribute xmlSchemaAttribute in xmlSchemaComplexContentExtension.Attributes) { ColumnSchema columnSchema = new ColumnSchema(this.Schema, xmlSchemaAttribute); if (columnSchemaCollection.ContainsKey(columnSchema.Name)) { columnSchemaCollection.Remove(columnSchema.Name); } columnSchemaCollection.Add(columnSchema); } } } } else { // This section will parse the simple particle. The particle has no inheritiance to evaluate. if (xmlSchemaComplexType.Particle is XmlSchemaSequence) { // Strongly type the XmlSchemaSequence member. XmlSchemaSequence xmlSchemaSequence = xmlSchemaComplexType.Particle as XmlSchemaSequence; // Each XmlSchemaElement on the Particle describes a column. foreach (XmlSchemaObject xmlSchemaObject in xmlSchemaSequence.Items) { ColumnSchema columnSchema = new ColumnSchema(this.Schema, xmlSchemaObject); if (columnSchemaCollection.ContainsKey(columnSchema.Name)) { columnSchemaCollection.Remove(columnSchema.Name); } columnSchemaCollection.Add(columnSchema); } } } }
public bool IsInheritedKey(ColumnSchema columnSchema) { return(this.IsPrimaryKeyColumn(columnSchema) && this.BaseTable != null); }
public bool IsAutogeneratedColumn(ColumnSchema columnSchema) { return(columnSchema.IsAutoIncrement || (this.IsPrimaryKeyColumn(columnSchema) && this.BaseTable != null && this.BaseTable.HasIdentityColumn)); }