/// <summary> /// Generates a property that gets the lock for the data model. /// </summary> public DataLockProperty(DataModelSchema dataModelSchema) { // /// <summary> // /// Gets the lock for the data model. // /// </summary> // public global::System.Threading.ReaderWriterLockSlim DataLock // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Gets the lock for the data model.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.CustomAttributes.AddRange(new CodeCustomAttributesForProperties()); this.Attributes = MemberAttributes.Public | MemberAttributes.Static; this.Type = new CodeGlobalTypeReference(typeof(ReaderWriterLockSlim)); this.Name = "DataLock"; // get // { // return this.dataLock; // } this.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(dataModelSchema.Name), String.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name))), "DataLock"))); // } }
/// <summary> /// A private field used to hold a complex sorting algorithm. /// </summary> public ComplexComparerField(OrderBySchema orderBySchema) { // private ComplexComparer<Sandbox.WorkingOrder.WorkingOrder> comparer; this.Attributes = MemberAttributes.Private; this.Type = new CodeTypeReference(string.Format("FluidTrade.Core.ComplexComparer<{0}>", orderBySchema.ResultType)); this.Name = CommonConversion.ToCamelCase(orderBySchema.Comparer); }
/// <summary> /// A private field used to hold a complex sorting algorithm. /// </summary> public SelectField(SelectSchema selectSchema) { // private ComplexComparer<Sandbox.WorkingOrder.WorkingOrder> comparer; this.Attributes = MemberAttributes.Private; this.Type = new CodeTypeReference(string.Format("System.Func<{0}, {1}>", selectSchema.SourceType, selectSchema.ResultType)); this.Name = CommonConversion.ToCamelCase(selectSchema.Selector); }
/// <summary> /// Creates a property to return a collection of the tables in the data model. /// </summary> /// <param name="dataModelSchema">The data model schema.</param> public TablesProperty(DataModelSchema dataModelSchema) { // /// <summary> // /// Gets the collection of tables contained in the DataModel. // /// </summary> // [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] // [global::System.ComponentModel.BrowsableAttribute(false)] // [global::System.ComponentModel.DesignerSerializationVisibility(global::System.ComponentModel.DesignerSerializationVisibility.Content)] // public static global::System.Data.DataTableCollection Tables { // get { // return FluidTrade.UnitTest.Server.DataModel.dataSet.Tables; // } // } this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(string.Format("Gets the collection of tables contained in the {0}.", dataModelSchema.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.CustomAttributes.AddRange(new CodeCustomAttributesForProperties()); this.Attributes = MemberAttributes.Public | MemberAttributes.Static; this.Type = new CodeGlobalTypeReference(typeof(System.Data.DataTableCollection)); this.Name = "Tables"; this.GetStatements.Add( new CodeMethodReturnStatement( new CodePropertyReferenceExpression( new CodePropertyReferenceExpression( new CodeTypeReferenceExpression(dataModelSchema.Name), String.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name))), "Tables"))); }
/// <summary> /// An internal vector field. /// </summary> public SchemaVectorField(PropertySchema propertySchema) { // internal System.Collections.Generic.IEnumerable<Sandbox.WorkingOrder.WorkingOrder> workingOrderList; this.Attributes = MemberAttributes.Assembly; this.Type = new CodeTypeReference(string.Format("{0}[]", propertySchema.Type)); this.Name = CommonConversion.ToCamelCase(propertySchema.Name); }
public CodeColumnExpressionCollection(ColumnSchema[] columns) { foreach (ColumnSchema columnSchema in columns) { this.Add(new CodeArgumentReferenceExpression(CommonConversion.ToCamelCase(columnSchema.Name))); } }
/// <summary> /// Creates a method to read an XML file. /// </summary> /// <param name="schema">The data model schema.</param> public ReadXmlMethod(DataModelSchema dataModelSchema) { // /// <summary> // /// Reads an XML file into the data model. // /// </summary> // /// <param name="fileName">The name of the file to read.</param> // public static void ReadXml(string fileName) // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Reads an XML file into the data model.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"fileName\">The name of the file to read.</param>", true)); this.Name = "ReadXml"; this.Attributes = MemberAttributes.Public | MemberAttributes.Static; this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(String)), "fileName")); // DataModel.dataSet.ReadXml(fileName); this.Statements.Add( new CodeMethodInvokeExpression( new CodePropertyReferenceExpression( new CodeTypeReferenceExpression(dataModelSchema.Name), String.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name))), "ReadXml", new CodeArgumentReferenceExpression("fileName"))); // } }
/// <summary> /// Creates a property that gets the collection of relationship between tables in the data model. /// </summary> /// <param name="dataModelSchema">The data model schema.</param> public RelationsProperty(DataModelSchema dataModelSchema) { // /// <summary> // /// Gets the collection of relations that link tables and allow navigation between parent tables and child tables. // /// </summary> // [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] // [global::System.ComponentModel.BrowsableAttribute(false)] // public static global::System.Data.DataRelationCollection Relations { // get { // return FluidTrade.UnitTest.Server.DataModel.dataSet.Relations; // } // } this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Gets the collection of relations that link tables and allow navigation between parent tables and child tables.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); // HACK - Put this line back in for official releases //this.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeGlobalTypeReference(typeof(System.Diagnostics.DebuggerNonUserCodeAttribute)))); this.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeGlobalTypeReference(typeof(System.ComponentModel.BrowsableAttribute)), new CodeAttributeArgument(new CodePrimitiveExpression(false)))); this.Attributes = MemberAttributes.Public | MemberAttributes.Static; this.Type = new CodeGlobalTypeReference(typeof(System.Data.DataRelationCollection)); this.Name = "Relations"; this.GetStatements.Add( new CodeMethodReturnStatement( new CodePropertyReferenceExpression( new CodePropertyReferenceExpression( new CodeTypeReferenceExpression(dataModelSchema.Name), String.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name))), "Relations"))); }
/// <summary> /// Creates a method to handle moving the deleted records from the active data model to the deleted data model. /// </summary> /// <param name="schema">The data model schema.</param> public AddTransactionMethod(DataModelSchema dataModelSchema) { // /// <summary> // /// Adds a transaction item to the log. // /// </summary> // /// <param name="iRow">The record to be added to the transaction log.</param> // /// <param name="data">An array of updated fields.</param> // [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] // [global::System.ComponentModel.BrowsableAttribute(false)] // internal static void AddTransaction(IRow iRow, object[] data) // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Adds a transaction item to the log.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"iRow\">The record to be added to the transaction log.</param>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"data\">An array of updated fields.</param>", true)); this.CustomAttributes.AddRange(new CodeCustomAttributesForProperties()); this.Name = "AddTransaction"; this.Attributes = MemberAttributes.Assembly | MemberAttributes.Static; this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(FluidTrade.Core.IRow)), "iRow")); this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(Object[])), "data")); // DataModel.dataModelDataSet.AddTransaction(iRow, data); this.Statements.Add( new CodeMethodInvokeExpression( new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(dataModelSchema.Name), String.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name))), "AddTransaction", new CodeArgumentReferenceExpression("iRow"), new CodeArgumentReferenceExpression("data"))); // } }
/// <summary> /// An internal scalar field. /// </summary> public SchemaScalarField(PropertySchema propertySchema) { // internal FluidTrade.Sandbox.WorkingOrder.AskPrice askPrice; this.Attributes = MemberAttributes.Assembly; this.Type = new CodeTypeReference(propertySchema.Type); this.Name = CommonConversion.ToCamelCase(propertySchema.Name); }
/// <summary> /// Creates an object that translates the parameters used for external methods to parameters for internal methods. /// </summary> public DestroyParameterMatrix(TableSchema tableSchema) { // Initialize the object. this.ExternalParameterItems = new SortedList <string, ExternalParameterItem>(); // Every set of update parameters requires a unique key to identify the record that is to be updated. UniqueConstraintParameterItem primaryKeyParameterItem = new UniqueConstraintParameterItem(); primaryKeyParameterItem.ActualDataType = typeof(Object[]); primaryKeyParameterItem.DeclaredDataType = typeof(Object[]); primaryKeyParameterItem.Description = String.Format("The required key for the {0} table.", tableSchema.Name); primaryKeyParameterItem.FieldDirection = FieldDirection.In; primaryKeyParameterItem.Name = String.Format("{0}Key", CommonConversion.ToCamelCase(tableSchema.Name)); this.ExternalParameterItems.Add(primaryKeyParameterItem.Name, primaryKeyParameterItem); // This will create an interface for the 'Destroy' method. foreach (KeyValuePair <string, ColumnSchema> columnPair in tableSchema.Columns) { // This column is turned into a simple parameter. ColumnSchema columnSchema = columnPair.Value; // The row version is required for the optimistic concurrency checking that is part of all update operations. if (columnSchema.IsRowVersion) { SimpleParameterItem simpleParameterItem = new SimpleParameterItem(); simpleParameterItem.ActualDataType = columnSchema.DataType; simpleParameterItem.ColumnSchema = columnSchema; simpleParameterItem.DeclaredDataType = columnSchema.DataType; simpleParameterItem.Description = String.Format("The required value for the {0} column.", CommonConversion.ToCamelCase(columnSchema.Name)); simpleParameterItem.FieldDirection = FieldDirection.In; simpleParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.ExternalParameterItems.Add(simpleParameterItem.Name, simpleParameterItem); } } }
/// <summary> /// A private field used to hold a complex filtering algorithm. /// </summary> public ComplexFilterField(WhereSchema whereSchema) { // private ComplexFilter<Sandbox.WorkingOrder.WorkingOrder> filter; this.Attributes = MemberAttributes.Private; this.Type = new CodeTypeReference(string.Format("FluidTrade.Core.ComplexFilter<{0}>", whereSchema.ResultType)); this.Name = CommonConversion.ToCamelCase(whereSchema.Predicate); }
/// <summary> /// Generates the method used to handle the Row Changed event. /// </summary> public FilterRowMethod(TableSchema tableSchema) { // /// <summary> // /// Filters a row from the results returned to a client. // /// </summary> // /// <param name="dataModelTransaction">The transaction in which this filter takes place.</param> // /// <param name="filterContext">A general purpose context for the read operation.</param> // /// <param name="containerContext">The Entity which contains this objects and maps to an ACL entry.</param> // /// <returns>True if the given row can be returned to the client, false otherwise.</returns> // private bool FilterRow(object context, object[] transactionLogItem) // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Filters a row from the results returned to a client.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"dataModelTransaction\">The transaction in which this filter takes place.</param>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"filterContext\">A general purpose context for the read operation.</param>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"containerContext\">The Entity which contains this objects and maps to an ACL entry.</param>", true)); this.Attributes = MemberAttributes.Private | MemberAttributes.Final; this.ReturnType = new CodeGlobalTypeReference(typeof(Boolean)); this.Name = "FilterRow"; this.Parameters.Add( new CodeParameterDeclarationExpression( new CodeGlobalTypeReference(typeof(FluidTrade.Core.IDataModelTransaction)), string.Format("{0}Transaction", CommonConversion.ToCamelCase(tableSchema.DataModel.Name)))); this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(Object)), "filterContext")); this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(Object)), "containerContext")); // return true; this.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(true))); // } }
/// <summary> /// Represents an expression that creates an object array using an array of ColumnSchemas. /// </summary> /// <param name="columns">The columns used to create the array expression.</param> public CodeKeyCreateExpression(ColumnSchema[] columns) { this.CreateType = new CodeGlobalTypeReference(typeof(Object)); foreach (ColumnSchema columnSchema in columns) { this.Initializers.Add(new CodeArgumentReferenceExpression(CommonConversion.ToCamelCase(columnSchema.Name))); } }
/// <summary> /// Creates a private field to hold the generic DataSet. /// </summary> public DataSetField(DataModelSchema dataModelSchema) { // // The generic data behind the strongly typed data model. // private static global::System.Data.DataSet dataSet; this.Attributes = MemberAttributes.Assembly | MemberAttributes.Static; this.Type = new CodeTypeReference(string.Format("{0}DataSet", dataModelSchema.Name)); this.Name = string.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name)); }
/// <summary> /// Creates an object that translates the parameters used for external methods to parameters for internal methods. /// </summary> public UpdateParameterMatrix(TableSchema tableSchema) { // Initialize the object. this.ExternalParameterItems = new SortedList <string, ExternalParameterItem>(); // Every set of update parameters requires a unique key to identify the record that is to be updated. UniqueConstraintParameterItem primaryKeyParameterItem = new UniqueConstraintParameterItem(); primaryKeyParameterItem.ActualDataType = typeof(Object[]); primaryKeyParameterItem.DeclaredDataType = typeof(Object[]); primaryKeyParameterItem.Description = String.Format("The required key for the {0} table.", tableSchema.Name); primaryKeyParameterItem.FieldDirection = FieldDirection.In; primaryKeyParameterItem.Name = String.Format("{0}Key", CommonConversion.ToCamelCase(tableSchema.Name)); this.ExternalParameterItems.Add(primaryKeyParameterItem.Name, primaryKeyParameterItem); // This will create an interface for the 'Update' method. foreach (KeyValuePair <string, ColumnSchema> columnPair in tableSchema.Columns) { // This column is turned into a simple parameter. ColumnSchema columnSchema = columnPair.Value; // If a column requires special processing, it is not handled with the rest of the parameters. bool isOrdinaryColumn = true; // The row version is required for the optimistic concurrency checking that is part of all update operations. if (columnSchema.IsRowVersion) { isOrdinaryColumn = false; SimpleParameterItem simpleParameterItem = new SimpleParameterItem(); simpleParameterItem.ActualDataType = columnSchema.DataType; simpleParameterItem.ColumnSchema = columnSchema; simpleParameterItem.DeclaredDataType = columnSchema.DataType; simpleParameterItem.Description = String.Format("The required value for the {0} column.", CommonConversion.ToCamelCase(columnSchema.Name)); simpleParameterItem.FieldDirection = FieldDirection.In; simpleParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.ExternalParameterItems.Add(simpleParameterItem.Name, simpleParameterItem); } // Ordinary parameters are passed from the external caller to the internal methods without modification or // interpretation. if (isOrdinaryColumn) { SimpleParameterItem simpleParameterItem = new SimpleParameterItem(); simpleParameterItem.ActualDataType = columnSchema.DataType; simpleParameterItem.ColumnSchema = columnSchema; simpleParameterItem.DeclaredDataType = typeof(Object); simpleParameterItem.Description = String.Format("The optional value for the {0} column.", CommonConversion.ToCamelCase(columnSchema.Name)); simpleParameterItem.FieldDirection = FieldDirection.In; simpleParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.ExternalParameterItems.Add(simpleParameterItem.Name, simpleParameterItem); } } }
/// <summary> /// Creates a field for the strongly typed row. /// </summary> public RowField(TableSchema tableSchema) { // // /// <summary> // /// The Department row that has been changed. // /// </summary> // private DepartmentRow departmentRow; this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(String.Format("The {0} row that has been changed.", tableSchema.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Attributes = MemberAttributes.Private; this.Type = new CodeTypeReference(String.Format("{0}Row", tableSchema.Name)); this.Name = String.Format("{0}Row", CommonConversion.ToCamelCase(tableSchema.Name)); }
/// <summary> /// Creates an array of values from a unique constraint that can be used for finding records. /// </summary> /// <param name="uniqueConstraintSchema">A description of a unique constraint.</param> /// <returns>An array of expressions that can be used as a key for finding records in a table.</returns> public CodeExpression[] CreateKey(UniqueConstraintSchema uniqueConstraintSchema) { // This will cycle through all the foreign and simple parameters looking for any columns that match up to the child // columns of the constraint. When found, they are placed in the array in the proper order to match up against the // given unique constraint. List <CodeExpression> keys = new List <CodeExpression>(); foreach (ColumnSchema uniqueColumn in uniqueConstraintSchema.Columns) { foreach (KeyValuePair <string, ExternalParameterItem> parameterPair in this.ExternalParameterItems) { // This correlates the unique constraint columns with the variables that have been created in the method to // hold the key values from the foreign tables. These variables exist outside of the conditional logic that // finds the parent row, so if the parent key is null, these values will also be null. However, since they're // still declared, they can be used to construct keys, which is useful when they're optional values. if (parameterPair.Value is ForeignKeyConstraintParameterItem) { ForeignKeyConstraintParameterItem foreignKeyConstraintParameterItem = parameterPair.Value as ForeignKeyConstraintParameterItem; ForeignKeyConstraintSchema foreignKeyConstraintSchema = foreignKeyConstraintParameterItem.ForeignKeyConstraintSchema; for (int columnIndex = 0; columnIndex < foreignKeyConstraintSchema.Columns.Length; columnIndex++) { if (uniqueColumn == foreignKeyConstraintSchema.Columns[columnIndex]) { foreach (ForeignKeyVariableItem foreignKeyVariableItem in foreignKeyConstraintParameterItem.ForeignKeyVariables) { if (foreignKeyConstraintSchema.Columns[columnIndex] == foreignKeyVariableItem.ColumnSchema) { keys.Add(foreignKeyVariableItem.Expression); } } } } } // This will match the columns described in the simple parameters to the columns in the unique constraint. if (parameterPair.Value is SimpleParameterItem) { SimpleParameterItem simpleParameterItem = parameterPair.Value as SimpleParameterItem; if (uniqueColumn == simpleParameterItem.ColumnSchema) { keys.Add(new CodeVariableReferenceExpression(CommonConversion.ToCamelCase(simpleParameterItem.ColumnSchema.Name))); } } } } // This array can be used as a key to find the record in a table. return(keys.ToArray()); }
/// <summary> /// Creates an object that translates the parameters used for external methods to parameters for internal methods. /// </summary> public CreateParameterMatrix(TableSchema tableSchema) { // Initialize the object. this.ExternalParameterItems = new SortedList <string, ExternalParameterItem>(); // This will create an interface for the 'Create' method. foreach (KeyValuePair <string, ColumnSchema> columnPair in tableSchema.Columns) { // This column is turned into a simple parameter. ColumnSchema columnSchema = columnPair.Value; // If a column requires special processing, it is not handled with the rest of the parameters. bool isOrdinaryColumn = true; // The row version is not used in the set of Create parameters. if (columnSchema.IsRowVersion) { isOrdinaryColumn = false; } // AutoIncremented columns can only be specified as output parameters. if (columnSchema.IsAutoIncrement) { isOrdinaryColumn = false; SimpleParameterItem simpleParameterItem = new SimpleParameterItem(); simpleParameterItem.ActualDataType = columnSchema.DataType; simpleParameterItem.ColumnSchema = columnSchema; simpleParameterItem.DeclaredDataType = columnSchema.DataType; simpleParameterItem.Description = String.Format("The generated value for the {0} column.", columnSchema.Name); simpleParameterItem.FieldDirection = FieldDirection.Out; simpleParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.ExternalParameterItems.Add(simpleParameterItem.Name, simpleParameterItem); } // The only complication for ordinary parameters is whether the data type can accept a default or not. if (isOrdinaryColumn) { SimpleParameterItem simpleParameterItem = new SimpleParameterItem(); bool isOptional = columnSchema.IsNullable || columnSchema.DefaultValue != DBNull.Value; simpleParameterItem.ActualDataType = columnSchema.DataType; simpleParameterItem.ColumnSchema = columnSchema; simpleParameterItem.DeclaredDataType = isOptional ? typeof(Object) : columnSchema.DataType; simpleParameterItem.Description = String.Format("The {0} value for the {1} column.", isOptional ? "optional" : "required", columnSchema.Name); simpleParameterItem.FieldDirection = FieldDirection.In; simpleParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.ExternalParameterItems.Add(simpleParameterItem.Name, simpleParameterItem); } } }
/// <summary> /// Creates a method to handle moving the deleted records from the active data model to the deleted data model. /// </summary> /// <param name="schema">The data model schema.</param> public ReadMethod(DataModelSchema dataModelSchema) { // /// <summary> // /// Collects the set of modified records that will reconcile the client data model to the master data model. // /// </summary> // /// <param name="identifier">A unique identifier of an instance of the data.</param> // /// <param name="sequence">The sequence of the client data model.</param> // /// <returns>An array of records that will reconcile the client data model to the server.</returns> // [global::FluidTrade.Core.ClaimsPrincipalPermission(global::System.Security.Permissions.SecurityAction.Demand, ClaimType=global::FluidTrade.Core.ClaimTypes.Read, Resource=global::FluidTrade.Core.Resources.Application)] // public object[] Read(global::System.Guid identifier, long sequence) // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Collects the set of modified records that will reconcile the client data model to the master data model.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"identifier\">A unique identifier of an instance of the data.</param>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"sequence\">The sequence of the client data model.</param>", true)); this.Comments.Add(new CodeCommentStatement("<returns>An array of records that will reconcile the client data model to the server.</returns>", true)); this.CustomAttributes.Add( new CodeAttributeDeclaration( new CodeGlobalTypeReference(typeof(OperationBehaviorAttribute)), new CodeAttributeArgument("TransactionScopeRequired", new CodePrimitiveExpression(true)))); //AR FB 408 - Remove Claims requirement //this.CustomAttributes.Add( // new CodeAttributeDeclaration( // new CodeGlobalTypeReference(typeof(ClaimsPrincipalPermission)), // new CodeAttributeArgument(new CodePropertyReferenceExpression(new CodeGlobalTypeReferenceExpression(typeof(SecurityAction)), "Demand")), // new CodeAttributeArgument("ClaimType", new CodePropertyReferenceExpression(new CodeGlobalTypeReferenceExpression(typeof(ClaimTypes)), "Read")), // new CodeAttributeArgument("Resource", new CodePropertyReferenceExpression(new CodeGlobalTypeReferenceExpression(typeof(Resources)), "Application")))); this.Name = "Read"; this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.ReturnType = new CodeGlobalTypeReference(typeof(Object[])); this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(Guid)), "identifier")); this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(Int64)), "sequence")); this.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(dataModelSchema.Name), String.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name))), "Read", new CodeArgumentReferenceExpression("identifier"), new CodeArgumentReferenceExpression("sequence")))); }
/// <summary> /// Creates a method that finds a row containing the given elements of an index. /// </summary> /// <param name="uniqueConstraintSchema">A description of a unique constraint.</param> public FindByMethod(UniqueConstraintSchema uniqueConstraintSchema) { // /// <summary> // /// Finds a row in the Gender table containing the key elements. // /// </summary> // /// <param name="genderCode">The GenderCode element of the key.</param> // /// <returns>The Gender row that contains the key elements, or null if there is no match.</returns> // public GenderRow Find(Teraque.UnitTest.Gender genderCode) { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(String.Format("Finds a row in the {0} table containing the key elements.", uniqueConstraintSchema.Table.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); foreach (ColumnSchema columnSchema in uniqueConstraintSchema.Columns) { this.Comments.Add(new CodeCommentStatement(String.Format("<param name=\"{0}\">The {1} element of the key.</param>", CommonConversion.ToCamelCase(columnSchema.Name), columnSchema.Name), true)); } this.Comments.Add(new CodeCommentStatement(String.Format("<returns>The {0} row that contains the key elements, or null if there is no match.</returns>", uniqueConstraintSchema.Table.Name), true)); this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.ReturnType = new CodeTypeReference(String.Format("{0}Row", uniqueConstraintSchema.Table.Name)); this.Name = "Find"; foreach (ColumnSchema columnSchema in uniqueConstraintSchema.Columns) { this.Parameters.Add(new CodeParameterDeclarationExpression(columnSchema.DataType, CommonConversion.ToCamelCase(columnSchema.Name))); } // // Return the strongly typed Object row that matches the key element(s). // return ((GenderRow)(base.Find(new object[] { // genderCode}))); this.Statements.Add(new CodeCommentStatement("Return the strongly typed Object row that matches the key element(s).")); List <CodeExpression> findByArguments = new List <CodeExpression>(); foreach (ColumnSchema columnSchema in uniqueConstraintSchema.Columns) { findByArguments.Add(new CodeArgumentReferenceExpression(CommonConversion.ToCamelCase(columnSchema.Name))); } this.Statements.Add( new CodeMethodReturnStatement( new CodeCastExpression( this.ReturnType, new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "Find", new CodeArrayCreateExpression(typeof(Object), findByArguments.ToArray()))))); // } }
/// <summary> /// Provides a default handler for to get a Reader Context. /// </summary> /// <param name="schema">The data model schema.</param> public GetFilterContextMethod(DataModelSchema dataModelSchema) { // /// <summary> // /// Provides a default handler for to get a Reader Context. // /// </summary> // private static object GetFilterContext() // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Provides a default handler for to get a Reader Context.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Attributes = MemberAttributes.Private; this.ReturnType = new CodeGlobalTypeReference(typeof(Object)); this.Name = "GetFilterContext"; this.Parameters.Add(new CodeParameterDeclarationExpression( string.Format("{0}Transaction", dataModelSchema.Name), string.Format("{0}Transaction", CommonConversion.ToCamelCase(dataModelSchema.Name)))); // return null; this.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null))); // } }
/// <summary> /// Generates a property that gets or sets a delegate for getting a context for a filtered read. /// </summary> /// <param name="tableSchema">A description of the data model.</param> public GetFilterContextHandlerProperty(DataModelSchema dataModelSchema) { // /// <summary> // /// Gets or sets a delegate used to get a context for a filtered read operation. // /// </summary> // public ObjectDelegate GetFilterContextHandler { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Gets or sets a delegate used to get a context for a filtered read operation.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.CustomAttributes.AddRange(new CodeCustomAttributesForProperties()); this.Attributes = MemberAttributes.Public | MemberAttributes.Static; this.Type = new CodeTypeReference("FilterContextDelegate"); this.Name = "GetFilterContextHandler"; // get { // return this.getFilterContextHandler; // } // set { // this.getFilterContextHandler = value; // } this.GetStatements.Add( new CodeMethodReturnStatement( new CodePropertyReferenceExpression( new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(dataModelSchema.Name), String.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name))), "GetFilterContextHandler"))); this.SetStatements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(dataModelSchema.Name), String.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name))), "GetFilterContextHandler"), new CodeVariableReferenceExpression("value"))); // } }
/// <summary> /// Creates a method to handle moving the deleted records from the active data model to the deleted data model. /// </summary> /// <param name="schema">The data model schema.</param> public ReconcileMethod(DataModelSchema dataModelSchema) { // /// <summary> // /// Determines whether the given records exist in the current data model. // /// </summary> // /// <param name="keys">An array of record keys and the index of the table to which they belong.</param> // /// <returns>An array of records keys that have been deleted.</returns> // [global::System.ServiceModel.OperationBehaviorAttribute(TransactionScopeRequired=true)] // public object[] Reconcile(object[] keys) // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Determines whether the given records exist in the current data model.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"keys\">An array of record keys and the index of the table to which they belong.</param>", true)); this.Comments.Add(new CodeCommentStatement("<returns>An array of records keys that have been deleted.</returns>", true)); this.CustomAttributes.Add( new CodeAttributeDeclaration( new CodeGlobalTypeReference(typeof(OperationBehaviorAttribute)), new CodeAttributeArgument("TransactionScopeRequired", new CodePrimitiveExpression(true)))); this.Name = "Reconcile"; this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.ReturnType = new CodeGlobalTypeReference(typeof(Object[])); this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(Object[])), "keys")); // return DataModel.dataModelDataSet.Reconcile(keys); this.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(dataModelSchema.Name), String.Format("{0}DataSet", CommonConversion.ToCamelCase(dataModelSchema.Name))), "Reconcile", new CodeArgumentReferenceExpression("keys")))); // } }
/// <summary> /// Creates a method to handle moving the deleted records from the active data model to the deleted data model. /// </summary> /// <param name="schema">The data model schema.</param> public ReadMethod(DataModelSchema dataModelSchema) { // /// <summary> // /// Collects the set of modified records that will reconcile the client data model to the master data model. // /// </summary> // /// <param name="identifier">A unique identifier of an instance of the data.</param> // /// <param name="sequence">The sequence of the client data model.</param> // /// <returns>An array of records that will reconcile the client data model to the server.</returns> // [global::FluidTrade.Core.ClaimsPrincipalPermission(global::System.Security.Permissions.SecurityAction.Demand, ClaimType=global::FluidTrade.Core.ClaimTypes.Read, Resource=global::FluidTrade.Core.Resources.Application)] // public object[] Read(global::System.Guid identifier, long sequence) // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Collects the set of modified records that will reconcile the client data model to the master data model.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"identifier\">A unique identifier of an instance of the data.</param>", true)); this.Comments.Add(new CodeCommentStatement("<param name=\"sequence\">The sequence of the client data model.</param>", true)); this.Comments.Add(new CodeCommentStatement("<returns>An array of records that will reconcile the client data model to the server.</returns>", true)); this.Name = "Read"; this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.ReturnType = new CodeGlobalTypeReference(typeof(Object[])); this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(Guid)), "identifier")); this.Parameters.Add(new CodeParameterDeclarationExpression(new CodeGlobalTypeReference(typeof(Int64)), "sequence")); // global::FluidTrade.Core.MiddleTierContext middleTierTransaction = global::FluidTrade.Core.MiddleTierContext.Current; CodeVariableReferenceExpression transactionExpression = new CodeVariableReferenceExpression( String.Format("{0}Transaction", CommonConversion.ToCamelCase(dataModelSchema.Name))); this.Statements.Add(new CodeCreateMiddleTierContextStatement(dataModelSchema, transactionExpression)); // object filterContext = DataModel.getFilterContextHandler(); this.Statements.Add( new CodeVariableDeclarationStatement( new CodeGlobalTypeReference(typeof(Object)), "filterContext", new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "getFilterContextHandler", transactionExpression))); // long transactionCount = 0L; this.Statements.Add( new CodeVariableDeclarationStatement(new CodeGlobalTypeReference(typeof(long)), "transactionCount", new CodePrimitiveExpression(0L))); // long currentSequence = sequence; this.Statements.Add( new CodeVariableDeclarationStatement( new CodeGlobalTypeReference(typeof(long)), "currentSequence", new CodeArgumentReferenceExpression("sequence"))); // try // { CodeTryCatchFinallyStatement tryTransactionLogLock = new CodeTryCatchFinallyStatement(); // DataModel.transactionLogLock.EnterReadLock(); tryTransactionLogLock.TryStatements.Add( new CodeMethodInvokeExpression( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "transactionLogLock"), "EnterReadLock")); // object[] dataHeader = new object[4]; tryTransactionLogLock.TryStatements.Add( new CodeVariableDeclarationStatement( new CodeGlobalTypeReference(typeof(Object[])), "dataHeader", new CodeArrayCreateExpression(new CodeGlobalTypeReference(typeof(Object[])), 4))); // dataHeader[0] = DataModel.identifier; tryTransactionLogLock.TryStatements.Add( new CodeAssignStatement( new CodeIndexerExpression(new CodeVariableReferenceExpression("dataHeader"), new CodePrimitiveExpression(0)), new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "identifier"))); // if ((identifier != DataModel.identifier)) // { CodeConditionStatement ifNewDataModel = new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeArgumentReferenceExpression("identifier"), CodeBinaryOperatorType.IdentityInequality, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "identifier"))); // sequence = long.MinValue; ifNewDataModel.TrueStatements.Add( new CodeAssignStatement( new CodeArgumentReferenceExpression("sequence"), new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(Int64)), "MinValue"))); tryTransactionLogLock.TryStatements.Add(ifNewDataModel); // } // global::System.Collections.ArrayList data = new global::System.Collections.ArrayList(); tryTransactionLogLock.TryStatements.Add( new CodeVariableDeclarationStatement( new CodeGlobalTypeReference(typeof(ArrayList)), "data", new CodeObjectCreateExpression(new CodeGlobalTypeReference(typeof(ArrayList))))); // global::System.Collections.Generic.LinkedListNode<TransactionLogItem> transactionNode = this.transactionLog.Last; tryTransactionLogLock.TryStatements.Add( new CodeVariableDeclarationStatement( new CodeTypeReference("global::System.Collections.Generic.LinkedListNode<TransactionLogItem>"), "transactionNode", new CodePropertyReferenceExpression( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "transactionLog"), "Last"))); // findLoop: tryTransactionLogLock.TryStatements.Add(new CodeLabeledStatement("findLoop")); // if ((transactionNode == transactionLog.First)) // { CodeConditionStatement ifFoundFist = new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression("transactionNode"), CodeBinaryOperatorType.IdentityEquality, new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("transactionLog"), "First"))); // goto logLoop; ifFoundFist.TrueStatements.Add(new CodeGotoStatement("logLoop")); // } tryTransactionLogLock.TryStatements.Add(ifFoundFist); // if ((transactionNode.Value.sequence <= sequence)) // { CodeConditionStatement ifTransactionFound = new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression( new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("transactionNode"), "Value"), "sequence"), CodeBinaryOperatorType.LessThanOrEqual, new CodeVariableReferenceExpression("sequence"))); // if ((transactionNode == this.transactionLog.Last)) // { CodeConditionStatement ifTransactionLast = new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression("transactionNode"), CodeBinaryOperatorType.IdentityEquality, new CodeFieldReferenceExpression( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "transactionLog"), "Last"))); // transactionNode = null; ifTransactionLast.TrueStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("transactionNode"), new CodePrimitiveExpression(null))); // } // else // { // transactionNode = transactionNode.Next; ifTransactionLast.FalseStatements.Add( new CodeAssignStatement(new CodeVariableReferenceExpression("transactionNode"), new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("transactionNode"), "Next"))); // } ifTransactionFound.TrueStatements.Add(ifTransactionLast); // goto logLoop; ifTransactionFound.TrueStatements.Add(new CodeGotoStatement("logLoop")); // } tryTransactionLogLock.TryStatements.Add(ifTransactionFound); // transactionNode = transactionNode.Previous; tryTransactionLogLock.TryStatements.Add( new CodeAssignStatement( new CodeVariableReferenceExpression("transactionNode"), new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("transactionNode"), "Previous"))); // goto findLoop; tryTransactionLogLock.TryStatements.Add(new CodeGotoStatement("findLoop")); // logLoop: tryTransactionLogLock.TryStatements.Add(new CodeLabeledStatement("logLoop")); // if ((transactionNode == null) || (transactionCount == this.readBufferSize)) // { CodeConditionStatement ifFull = new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression("transactionNode"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null)), CodeBinaryOperatorType.BooleanOr, new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression("transactionCount"), CodeBinaryOperatorType.IdentityEquality, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "readBufferSize")))); // goto endLoop; ifFull.TrueStatements.Add(new CodeGotoStatement("endLoop")); // } tryTransactionLogLock.TryStatements.Add(ifFull); // object[] transactionLogItem = ((object[])(transactionNode.Value.data)); tryTransactionLogLock.TryStatements.Add( new CodeVariableDeclarationStatement( new CodeGlobalTypeReference(typeof(Object[])), "transactionLogItem", new CodeCastExpression( new CodeGlobalTypeReference(typeof(Object[])), new CodeFieldReferenceExpression( new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("transactionNode"), "Value"), "data")))); // global::System.Data.DataTable dataTable = DataModel.dataSet.Tables[((int)(transactionLogItem[1]))]; tryTransactionLogLock.TryStatements.Add( new CodeVariableDeclarationStatement( new CodeGlobalTypeReference(typeof(DataTable)), "dataTable", new CodeIndexerExpression( new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Tables"), new CodeCastExpression( new CodeGlobalTypeReference(typeof(Int32)), new CodeIndexerExpression( new CodeVariableReferenceExpression("transactionLogItem"), new CodePrimitiveExpression(1)))))); // if ((((ITable)(dataTable)).FilterRowHandler(dataModelTransaction, filterContext, transactionNode.Value.containerContext))) // { CodeConditionStatement ifFiltered = new CodeConditionStatement( new CodeMethodInvokeExpression( new CodeCastExpression(new CodeGlobalTypeReference(typeof(FluidTrade.Core.ITable)), new CodeVariableReferenceExpression("dataTable")), "FilterRowHandler", new CodeVariableReferenceExpression(String.Format("{0}Transaction", CommonConversion.ToCamelCase(dataModelSchema.Name))), new CodeVariableReferenceExpression("filterContext"), new CodeFieldReferenceExpression( new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("transactionNode"), "Value"), "containerContext"))); // data.Add(transactionLogItem); ifFiltered.TrueStatements.Add( new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("data"), "Add", new CodeVariableReferenceExpression("transactionLogItem"))); // } tryTransactionLogLock.TryStatements.Add(ifFiltered); // currentSequence = transactionNode.Value.sequence; tryTransactionLogLock.TryStatements.Add( new CodeAssignStatement( new CodeVariableReferenceExpression("currentSequence"), new CodeFieldReferenceExpression( new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("transactionNode"), "Value"), "sequence"))); // transactionNode = transactionNode.Next; tryTransactionLogLock.TryStatements.Add( new CodeAssignStatement( new CodeVariableReferenceExpression("transactionNode"), new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("transactionNode"), "Next"))); // transactionCount = (transactionCount + 1); tryTransactionLogLock.TryStatements.Add( new CodeAssignStatement( new CodeVariableReferenceExpression("transactionCount"), new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression("transactionCount"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1)))); // goto logLoop; tryTransactionLogLock.TryStatements.Add(new CodeGotoStatement("logLoop")); // endLoop: tryTransactionLogLock.TryStatements.Add(new CodeLabeledStatement("endLoop")); // dataHeader[1] = currentSequence; tryTransactionLogLock.TryStatements.Add( new CodeAssignStatement( new CodeIndexerExpression(new CodeVariableReferenceExpression("dataHeader"), new CodePrimitiveExpression(1)), new CodeVariableReferenceExpression("currentSequence"))); // dataHeader[2] = this.transactionLog.Last.Value.sequence; tryTransactionLogLock.TryStatements.Add( new CodeAssignStatement( new CodeIndexerExpression(new CodeVariableReferenceExpression("dataHeader"), new CodePrimitiveExpression(2)), new CodeFieldReferenceExpression( new CodePropertyReferenceExpression( new CodePropertyReferenceExpression( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "transactionLog"), "Last"), "Value"), "sequence"))); // dataHeader[3] = data.ToArray(); tryTransactionLogLock.TryStatements.Add( new CodeAssignStatement( new CodeIndexerExpression(new CodeVariableReferenceExpression("dataHeader"), new CodePrimitiveExpression(3)), new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("data"), "ToArray"))); // return dataHeader; tryTransactionLogLock.TryStatements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("dataHeader"))); // finally // { // DataModel.transactionLogLock.ExitReadLock(); tryTransactionLogLock.FinallyStatements.Add( new CodeMethodInvokeExpression( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "transactionLogLock"), "ExitReadLock")); // } this.Statements.Add(tryTransactionLogLock); // } }
/// <summary> /// Creates a property for from the XML Schema definition. /// </summary> public SchemaProperty(PropertySchema propertySchema) { // /// <summary> // /// Price // /// <summary> // public decimal Price // { // get // { // return this.price; // } // set // { // // } this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(propertySchema.Name, true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.Type = propertySchema.MaxOccurs == 1 ? new CodeTypeReference(propertySchema.Type) : new CodeTypeReference(string.Format("System.Collections.Generic.IEnumerable<{0}>", propertySchema.Type)); this.Name = propertySchema.Name; this.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), CommonConversion.ToCamelCase(propertySchema.Name)))); this.SetStatements.Add(new CodeSnippetStatement()); // } }
/// <summary> /// Generates the constructor for the generated class. /// </summary> /// <param name="classSchema">A description of a Type.</param> public SchemaConstructor(ClassSchema classSchema) { // /// <summary> // /// Creates a FluidTrade.Sandbox.WorkingOrder.WorkingOrder. // /// </summary> // public WorkingOrder(FluidTrade.Sandbox.WorkingOrderRow workingOrderRow) // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(string.Format("Creates a {0}.", classSchema.Type), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Attributes = MemberAttributes.Public; // This will run through each of the members of the class an initialize the complex data types. If the element allows // only one occurance of an element, then a single object is created. If the element allows many, then a list is // created. Basic data types are not constructred here. foreach (PropertySchema propertySchema in classSchema.Properties) { // For scalar properties, the property is created and then populated using the setters. if (propertySchema.MaxOccurs == 1) { // this.askPrice = new FluidTrade.Sandbox.WorkingOrder.AskPrice(); CodeFieldReferenceExpression fieldExpression = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), CommonConversion.ToCamelCase(propertySchema.Name)); this.Statements.Add(new CodeAssignStatement(fieldExpression, new CodeObjectCreateExpression(new CodeTypeReference(propertySchema.Type)))); } } }
/// <summary> /// Creates a property for from the XML Schema definition. /// </summary> public ComplexFilterProperty(WhereSchema whereSchema) { // /// <summary> // /// Gets or sets the complex filter used to remove records from the result set. // /// <summary> // public ComplexFilter<Sandbox.WorkingOrder.WorkingOrder> Filter // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement("Gets or sets the complex filter used to remove records from the result set.", true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.Type = new CodeTypeReference(string.Format("FluidTrade.Core.ComplexFilter<{0}>", whereSchema.ResultType)); this.Name = whereSchema.Predicate; // get // { // return FluidTrade.Sandbox.WorkingOrderHeader.WorkingOrderHeader.filter; // } this.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), CommonConversion.ToCamelCase(whereSchema.Predicate)))); this.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), CommonConversion.ToCamelCase(whereSchema.Predicate)), new CodeArgumentReferenceExpression("value"))); // } }
/// <summary> /// Creates a method that finds a row containing the given elements of an index. /// </summary> /// <param name="uniqueConstraintSchema">A description of a unique constraint.</param> public FindByMethod(UniqueConstraintSchema uniqueConstraintSchema) { // /// <summary> // /// Finds a row in the Configuration table containing the key elements. // /// </summary> // /// <param name="configurationId">The ConfigurationId element of the key.</param> // /// <param name="relationName">The RelationName element of the key.</param> // /// <returns>The Configuration row that contains the key elements, or null if there is no match.</returns> // public ConfigurationRow Find(string configurationId, string relationName) { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(string.Format("Finds a row in the {0} table containing the key elements.", uniqueConstraintSchema.Table.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); foreach (ColumnSchema columnSchema in uniqueConstraintSchema.Columns) { this.Comments.Add(new CodeCommentStatement(string.Format("<param name=\"{0}\">The {1} element of the key.</param>", CommonConversion.ToCamelCase(columnSchema.Name), columnSchema.Name), true)); } this.Comments.Add(new CodeCommentStatement(string.Format("<returns>The {0} row that contains the key elements, or null if there is no match.</returns>", uniqueConstraintSchema.Table.Name), true)); this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.ReturnType = new CodeTypeReference(string.Format("{0}Row", uniqueConstraintSchema.Table.Name)); this.Name = "Find"; foreach (ColumnSchema columnSchema in uniqueConstraintSchema.Columns) { this.Parameters.Add(new CodeParameterDeclarationExpression(columnSchema.DataType, CommonConversion.ToCamelCase(columnSchema.Name))); } // try { // DataModel.Configuration.AcquireLock(); // return ((ConfigurationRow)(base.Find(new object[] { // configurationId, // relationName}))); // } // catch (global::System.ArgumentException argumentException) { // throw new global::System.ServiceModel.FaultException<ArgumentFault>(new global::FluidTrade.Core.ArgumentFault(argumentException.Message)); // } // finally { // DataModel.Configuration.ReleaseLock(); // } CodeTryCatchFinallyStatement tryCatchFinallyStatement = new CodeTryCatchFinallyStatement(); CodePropertyReferenceExpression tableExpression = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(string.Format("{0}", uniqueConstraintSchema.Table.DataModel.Name)), uniqueConstraintSchema.Table.Name); tryCatchFinallyStatement.TryStatements.Add( new CodeMethodInvokeExpression( new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(uniqueConstraintSchema.Table.DataModel.Name), "DataLock"), "EnterReadLock")); tryCatchFinallyStatement.TryStatements.Add(new CodeMethodReturnStatement(new CodeCastExpression(this.ReturnType, new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "Find", new CodeKeyCreateExpression(uniqueConstraintSchema.Columns))))); CodeCatchClause catchArgumentException = new CodeCatchClause("argumentException", new CodeGlobalTypeReference(typeof(System.ArgumentException))); catchArgumentException.Statements.Add(new CodeThrowArgumentExceptionStatement(new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("argumentException"), "Message"))); tryCatchFinallyStatement.CatchClauses.Add(catchArgumentException); CodeCatchClause catchFormatException = new CodeCatchClause("formatException", new CodeGlobalTypeReference(typeof(System.FormatException))); catchFormatException.Statements.Add(new CodeThrowFormatExceptionStatement(new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("formatException"), "Message"))); tryCatchFinallyStatement.CatchClauses.Add(catchFormatException); tryCatchFinallyStatement.FinallyStatements.Add( new CodeMethodInvokeExpression( new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(uniqueConstraintSchema.Table.DataModel.Name), "DataLock"), "ExitReadLock")); this.Statements.Add(tryCatchFinallyStatement); // } }
/// <summary> /// Creates an object that translates the parameters used for external methods to parameters for internal methods. /// </summary> public CreateExParameterMatrix(TableSchema tableSchema) { // Initialize the object. this.ExternalParameterItems = new SortedList <string, ExternalParameterItem>(); this.CreateParameterItems = new SortedList <string, InternalParameterItem>(); this.UpdateParameterItems = new SortedList <string, InternalParameterItem>(); // Place all the columns of the table in a list that will drive the creation of parameters. Those that columns that // are native to this table will be left in the list. Those columns that are part of a foreign constraint will be // replace in the final argument list with internal values that can be used to look up the actual value. List <ColumnSchema> columnList = new List <ColumnSchema>(); foreach (KeyValuePair <string, ColumnSchema> keyValuePair in tableSchema.Columns) { columnList.Add(keyValuePair.Value); } // The 'CreateEx' method doesn't have an explicit unique key in the parameter list like the 'Update' and 'Delete', so // there's no explicit input parameter to which to associate the unique row that is the target of the operation. This // creates an implicit unique index which will be resolved using the explicit input parameters to this method. this.RowExpression = new CodeRandomVariableReferenceExpression(); this.UniqueKeyExpression = new CodeRandomVariableReferenceExpression(); // Every internal update method requires a primary key specification. This key is created from the primary key columns // of the existing row. While it may seem redundant to find a row before calling the internal method to update that // same row, one of the primary purposes of the external method is to short-circuit the optimistic concurrency // checking. To do that, the row version from the existing row is required. The same row that provides the current // row version also provides the unique key to call the internal method. However, Any one of the unique constraints // associated with the table can be used from the external interface to look up the row before the internal method is // called. This makes it possible to change the primary key of a given column which is a requirement of a true // relational database model. Said differently, this parameter item acts like the 'WHERE' clause in an SQL statement. InternalParameterItem primaryKeyParameterItem = new InternalParameterItem(); List <CodeExpression> primaryKeyExpressions = new List <CodeExpression>(); foreach (ColumnSchema columnSchema in tableSchema.PrimaryKey.Columns) { primaryKeyExpressions.Add(new CodePropertyReferenceExpression(this.RowExpression, columnSchema.Name)); } primaryKeyParameterItem.Expression = new CodeArrayCreateExpression(new CodeGlobalTypeReference(typeof(Object)), primaryKeyExpressions.ToArray()); primaryKeyParameterItem.Name = String.Format("{0}Key", CommonConversion.ToCamelCase(tableSchema.Name)); this.UpdateParameterItems.Add(primaryKeyParameterItem.Name, primaryKeyParameterItem); // This will make sure that all the constraints on a table are satisfied by the list of parameters. foreach (ForeignKeyConstraintSchema foreignKeyConstraintSchema in tableSchema.ForeignKeyConstraintSchemas) { // No attempt will be made to resolve complex, redundant constraints as the same data can be found from simpler // ones. The presence of the redundant, complex foreign keys will only confuse the interface. if (foreignKeyConstraintSchema.IsRedundant) { continue; } // This item describes an input parameter that uses one or more external identifiers as a keys to parent tables. // Those parent tables provide the actual values that are used to update the record. This allows an external // interface to use external identifiers from related tables. ForeignKeyConstraintParameterItem foreignKeyConstraintParameterItem = new ForeignKeyConstraintParameterItem(); // This is the foreign constraint that is to be resolved with this parameter. foreignKeyConstraintParameterItem.ForeignKeyConstraintSchema = foreignKeyConstraintSchema; foreignKeyConstraintParameterItem.ActualDataType = typeof(Object[]); foreignKeyConstraintParameterItem.DeclaredDataType = typeof(Object[]); foreignKeyConstraintParameterItem.Description = foreignKeyConstraintParameterItem.IsNullable ? String.Format("An optional unique key for the parent {0} record.", foreignKeyConstraintSchema.RelatedTable) : String.Format("A required unique key for the parent {0} record.", foreignKeyConstraintSchema.RelatedTable); foreignKeyConstraintParameterItem.FieldDirection = FieldDirection.In; foreignKeyConstraintParameterItem.Name = String.Format("{0}Key", CommonConversion.ToCamelCase(foreignKeyConstraintSchema.RelatedTable.Name)); if (!foreignKeyConstraintSchema.IsDistinctPathToParent) { foreignKeyConstraintParameterItem.Name += "By"; foreach (ColumnSchema columnSchema in foreignKeyConstraintSchema.Columns) { foreignKeyConstraintParameterItem.Name += columnSchema.Name; } } foreignKeyConstraintParameterItem.IsNullable = true; foreach (ColumnSchema columnSchema in foreignKeyConstraintSchema.Columns) { if (!columnSchema.IsNullable) { foreignKeyConstraintParameterItem.IsNullable = false; } } this.ExternalParameterItems.Add(foreignKeyConstraintParameterItem.Name, foreignKeyConstraintParameterItem); // This constructs a mapping between the foreign key parameter that is provided to the external method and the // individual parameters that are needed by the internal method. foreach (ColumnSchema columnSchema in foreignKeyConstraintSchema.Columns) { // This creates an intermediate variable to hold a value collected from the foreign keys. When creating an // object, the required values are strongly typed. Optional columns and columns with defaults are defined as // generic types so they can be nulled if no cooresponding value is provided. ForeignKeyVariableItem foreignKeyVariableItem = new ForeignKeyVariableItem(); foreignKeyVariableItem.ColumnSchema = columnSchema; foreignKeyVariableItem.DataType = columnSchema.IsNullable || columnSchema.DefaultValue != DBNull.Value ? typeof(Object) : columnSchema.DataType; foreignKeyVariableItem.Expression = new CodeRandomVariableReferenceExpression(); foreignKeyConstraintParameterItem.ForeignKeyVariables.Add(foreignKeyVariableItem); // This creates an internal parameter for the 'Create' method from the elements of the foreign key. InternalParameterItem createParameterItem = new InternalParameterItem(); createParameterItem.ColumnSchema = columnSchema; createParameterItem.Expression = foreignKeyVariableItem.Expression; createParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.CreateParameterItems.Add(createParameterItem.Name, createParameterItem); // This creates an internal parameter for the 'Update' method from the elements of the foreign key. InternalParameterItem updateParameterItem = new InternalParameterItem(); updateParameterItem.ColumnSchema = columnSchema; updateParameterItem.Expression = foreignKeyVariableItem.Expression; updateParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.UpdateParameterItems.Add(updateParameterItem.Name, updateParameterItem); // Any items resolved using foreign constraints are removed from the list of input parameters. The key is the // means of evaluating the column's value and it can't be added directly from the outside world. columnList.Remove(columnSchema); } } // At this point, all the parameters that need to be resolved with foreign keys have been added to the list of external // and internal parameters and their related columns have been removed from the list of input parameters. This next // block will add the remaining items to the list of external and internal parameters. foreach (ColumnSchema columnSchema in columnList) { // If a column requires special processing, it is not handled with the rest of the parameters. bool isOrdinaryColumn = true; // Since the external world doesn't have access to the row versions, they must be removed from the input // parameters. A mechanism is constructed internal to the method to defeat the optimistic concurrency checking. if (columnSchema.IsRowVersion) { // This is no ordinary column. isOrdinaryColumn = false; // This parameters is used for the internal 'Update' methods to defeat the optimistic concurrency checking. It is not // part of the 'Create' interface. InternalParameterItem internalParameterItem = new InternalParameterItem(); internalParameterItem.ColumnSchema = columnSchema; internalParameterItem.Expression = new CodePropertyReferenceExpression(this.RowExpression, "RowVersion"); internalParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.UpdateParameterItems.Add(internalParameterItem.Name, internalParameterItem); } // AutoIncremented columns can only be specified as output parameters. if (columnSchema.IsAutoIncrement) { // This is no ordinary column. isOrdinaryColumn = false; // Create an outpt parameter for the AutoIncremented values as the values are always generated by the middle // tier. SimpleParameterItem simpleParameterItem = new SimpleParameterItem(); simpleParameterItem.ActualDataType = columnSchema.DataType; simpleParameterItem.ColumnSchema = columnSchema; simpleParameterItem.DeclaredDataType = columnSchema.DataType; simpleParameterItem.Description = String.Format("The output value for the {0} column.", columnSchema.Name); simpleParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.ExternalParameterItems.Add(simpleParameterItem.Name, simpleParameterItem); // Note that when an object with an AutoIncrement column is added, the column is specified as an output // parameter. InternalParameterItem createParameterItem = new InternalParameterItem(); createParameterItem.ColumnSchema = columnSchema; createParameterItem.Expression = new CodeDirectionExpression(FieldDirection.Out, new CodeArgumentReferenceExpression(simpleParameterItem.Name)); createParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.CreateParameterItems.Add(createParameterItem.Name, createParameterItem); // The AutoIncrement column is a simple input parameter when the record is updated. InternalParameterItem updateParameterItem = new InternalParameterItem(); updateParameterItem.ColumnSchema = columnSchema; updateParameterItem.Expression = new CodeArgumentReferenceExpression(simpleParameterItem.Name); updateParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.UpdateParameterItems.Add(updateParameterItem.Name, updateParameterItem); } // Ordinary parameters are passed from the external caller to the internal methods without modification or // interpretation. if (isOrdinaryColumn) { // Create a simple input parameter from the column information. The only complication is whether the value // must be provided by the caller or is optional. SimpleParameterItem simpleParameterItem = new SimpleParameterItem(); bool isOptional = columnSchema.IsNullable || columnSchema.DefaultValue != DBNull.Value; simpleParameterItem.ActualDataType = columnSchema.DataType; simpleParameterItem.ColumnSchema = columnSchema; simpleParameterItem.DeclaredDataType = isOptional ? typeof(Object) : columnSchema.DataType; simpleParameterItem.Description = String.Format("The {0} value for the {1} column.", isOptional ? "optional" : "required", CommonConversion.ToCamelCase(columnSchema.Name)); simpleParameterItem.FieldDirection = FieldDirection.In; simpleParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.ExternalParameterItems.Add(simpleParameterItem.Name, simpleParameterItem); // This is how the parameter will be interpreted by the 'Insert' and 'Update' internal methods. InternalParameterItem internalParameterItem = new InternalParameterItem(); internalParameterItem.ColumnSchema = columnSchema; internalParameterItem.Expression = new CodeArgumentReferenceExpression(CommonConversion.ToCamelCase(columnSchema.Name)); internalParameterItem.Name = CommonConversion.ToCamelCase(columnSchema.Name); this.CreateParameterItems.Add(internalParameterItem.Name, internalParameterItem); this.UpdateParameterItems.Add(internalParameterItem.Name, internalParameterItem); } } // A configuration identifier is is required on all interface methods except the 'Configuration' table. While not // every method requires the resolution of multiple external keys, the decision to add this for column was made for // consistency. The idea that the external interface shouldn't break if a new unique key is added to the hierarchy. // This means more work up front to configure the external interfaces, but it means less work later on as the relations // and schema change. if (tableSchema.Name != "Configuration") { ExternalParameterItem externalParameterItem = new ExternalParameterItem(); externalParameterItem.ActualDataType = typeof(String); externalParameterItem.DeclaredDataType = typeof(String); externalParameterItem.Description = "Selects a configuration of unique indices used to resolve external identifiers."; externalParameterItem.FieldDirection = FieldDirection.In; externalParameterItem.IsNullable = false; externalParameterItem.Name = "configurationId"; this.ExternalParameterItems.Add(externalParameterItem.Name, externalParameterItem); } }