private static void writeCreateForSingleRowUpdateMethod(
            DBConnection cn, string tableName, bool isRevisionHistoryTable, bool isRevisionHistoryClass, string methodNameSuffix)
        {
            // header
            CodeGenerationStatics.AddSummaryDocComment(
                writer,
                "Creates a modification object in single-row update mode with the specified current data. All column values in this object will have HasChanged = false, despite being initialized. This object can then be used to do a piecemeal update of the " +
                tableName + " table.");
            writer.Write(
                "public static " + GetClassName(cn, tableName, isRevisionHistoryTable, isRevisionHistoryClass) + " CreateForSingleRowUpdate" + methodNameSuffix +
                "( ");
            writeColumnParameterDeclarations(columns.AllColumnsExceptRowVersion);
            writer.WriteLine(" ) {");


            // body

            writer.WriteLine(
                "var mod = new " + GetClassName(cn, tableName, isRevisionHistoryTable, isRevisionHistoryClass) + " { modType = ModificationType.Update };");

            // Use the values of key columns as conditions.
            writer.WriteLine("mod.conditions = new List<" + DataAccessStatics.GetTableConditionInterfaceName(cn, database, tableName) + ">();");
            foreach (var column in columns.KeyColumns)
            {
                writer.WriteLine(
                    "mod.conditions.Add( new " + DataAccessStatics.GetEqualityConditionClassName(cn, database, tableName, column) + "( " +
                    EwlStatics.GetCSharpIdentifier(column.CamelCasedName) + " ) );");
            }

            writeColumnValueAssignmentsFromParameters(columns.AllColumnsExceptRowVersion, "mod");
            writer.WriteLine("mod.markColumnValuesUnchanged();");
            writer.WriteLine("return mod;");
            writer.WriteLine("}");
        }
        internal static void Generate(DBConnection cn, TextWriter writer, string baseNamespace, Database database, IEnumerable <string> tableNames)
        {
            writer.WriteLine("namespace " + baseNamespace + "." + database.SecondaryDatabaseName + "TableConstants {");
            foreach (var table in tableNames)
            {
                CodeGenerationStatics.AddSummaryDocComment(writer, "This object represents the constants of the " + table + " table.");
                writer.WriteLine("public class " + EwlStatics.GetCSharpIdentifier(table.TableNameToPascal(cn) + "Table") + " {");

                CodeGenerationStatics.AddSummaryDocComment(writer, "The name of this table.");
                writer.WriteLine("public const string Name = \"" + table + "\";");

                foreach (var column in new TableColumns(cn, table, false).AllColumnsExceptRowVersion)
                {
                    CodeGenerationStatics.AddSummaryDocComment(writer, "Contains schema information about this column.");
                    writer.WriteLine("public class " + EwlStatics.GetCSharpIdentifier(column.PascalCasedNameExceptForOracle + "Column") + " {");

                    CodeGenerationStatics.AddSummaryDocComment(writer, "The name of this column.");
                    writer.WriteLine("public const string Name = \"" + column.Name + "\";");

                    CodeGenerationStatics.AddSummaryDocComment(
                        writer,
                        "The size of this column. For varchars, this is the length of the biggest string that can be stored in this column.");
                    writer.WriteLine("public const int Size = " + column.Size + ";");

                    writer.WriteLine("}");
                }

                writer.WriteLine("}");
            }
            writer.WriteLine("}");
        }
예제 #3
0
        private static void writeInequalityConditionClasses(DBConnection cn, TextWriter writer, string table)
        {
            // NOTE: This kind of sucks. It seems like we could use generics to not have to write N of these methods into ISU.cs.
            writer.WriteLine("public static class " + EwlStatics.GetCSharpIdentifier(table.TableNameToPascal(cn) + "TableInequalityConditions") + " {");
            foreach (var column in new TableColumns(cn, table, false).AllColumnsExceptRowVersion)
            {
                CodeGenerationStatics.AddSummaryDocComment(writer, "A condition that narrows the scope of a command.");
                writer.WriteLine("public class " + GetConditionClassName(column) + ": " + GetTableConditionInterfaceName(cn, table) + " {");
                writer.WriteLine("private readonly InequalityCondition.Operator op; ");
                writer.WriteLine("private readonly " + column.DataTypeName + " value;");

                CodeGenerationStatics.AddSummaryDocComment(
                    writer,
                    "Creates a condition to narrow the scope of a command. Expression will read 'valueInDatabase op yourValue'. So new InequalityCondition( Operator.GreaterThan, value ) will turn into 'columnName > @value'.");
                writer.WriteLine("public " + GetConditionClassName(column) + "( InequalityCondition.Operator op, " + column.DataTypeName + " value ) {");
                writer.WriteLine("this.op = op;");
                writer.WriteLine("this.value = value;");
                writer.WriteLine("}");

                var colVal = column.GetCommandColumnValueExpression("value");
                writer.WriteLine("InlineDbCommandCondition TableCondition.CommandCondition { get { return new InequalityCondition( op, " + colVal + " ); } }");
                writer.WriteLine("}");
            }
            writer.WriteLine("}");               // class
        }
        private static void writeFieldsAndPropertiesForColumn(Column column)
        {
            var columnIsReadOnly = !columns.DataColumns.Contains(column);

            writer.WriteLine(
                "private readonly DataValue<" + column.DataTypeName + "> " + getColumnFieldName(column) + " = new DataValue<" + column.DataTypeName + ">();");
            CodeGenerationStatics.AddSummaryDocComment(
                writer,
                "Gets " + (columnIsReadOnly ? "" : "or sets ") + "the value for the " + column.Name +
                " column. Throws an exception if the value has not been initialized. " + getComment(column));
            var propertyDeclarationBeginning = "public " + column.DataTypeName + " " + EwlStatics.GetCSharpIdentifier(column.PascalCasedNameExceptForOracle) +
                                               " { get { return " + getColumnFieldName(column) + ".Value; } ";

            if (columnIsReadOnly)
            {
                writer.WriteLine(propertyDeclarationBeginning + "}");
            }
            else
            {
                writer.WriteLine(propertyDeclarationBeginning + "set { " + getColumnFieldName(column) + ".Value = value; } }");

                CodeGenerationStatics.AddSummaryDocComment(
                    writer,
                    "Indicates whether or not the value for the " + column.Name +
                    " has been set since object creation or the last call to Execute, whichever was latest.");
                writer.WriteLine(
                    "public bool " + EwlStatics.GetCSharpIdentifier(column.PascalCasedNameExceptForOracle + "HasChanged") + " { get { return " +
                    getColumnFieldName(column) + ".Changed; } }");
            }
        }
        internal WebItemGeneralData(
            string webProjectPath, string pathRelativeToProject, bool includeFileExtensionInClassName, WebProject webProjectConfiguration)
        {
            this.pathRelativeToProject = pathRelativeToProject;

            // Get the URL for this item. "Plain old class" entity setups do not have URLs.
            urlRelativeToProject = pathRelativeToProject.EndsWith(".cs") ? "" : pathRelativeToProject.Replace(System.IO.Path.DirectorySeparatorChar, '/');

            // Load this item's code if it exists.
            path = EwlStatics.CombinePaths(webProjectPath, pathRelativeToProject);
            var codePath = path.EndsWith(".cs") ? path : path + ".cs";

            code = File.Exists(codePath) ? File.ReadAllText(codePath) : "";

            // Attempt to get the namespace from the code. If this fails, use a namespace based on the item's path in the project.
            foreach (Match match in Regex.Matches(code, @"namespace\s(?<namespace>.*)\s{"))
            {
                itemNamespace = match.Groups["namespace"].Value;
            }
            if (itemNamespace == null)
            {
                itemNamespace = getNamespaceFromFilePath(webProjectConfiguration.NamespaceAndAssemblyName, pathRelativeToProject);
            }

            className = EwlStatics.GetCSharpIdentifier(
                System.IO.Path.GetFileNameWithoutExtension(path).CapitalizeString() +
                (includeFileExtensionInClassName ? System.IO.Path.GetExtension(path).CapitalizeString() : ""));
            this.webProjectConfiguration = webProjectConfiguration;
        }
 private static void writeColumnParameterDeclarations(IEnumerable <Column> columns)
 {
     writer.Write(
         StringTools.ConcatenateWithDelimiter(
             ", ",
             columns.Select(i => i.DataTypeName + " " + EwlStatics.GetCSharpIdentifier(i.CamelCasedName)).ToArray()));
 }
 internal static string GetClassName(DBConnection cn, string table, bool isRevisionHistoryTable, bool isRevisionHistoryClass)
 {
     return(EwlStatics.GetCSharpIdentifier(
                isRevisionHistoryTable && !isRevisionHistoryClass
                                 ? "Direct" + table.TableNameToPascal(cn) + "ModificationWithRevisionBypass"
                                 : table.TableNameToPascal(cn) + "Modification"));
 }
예제 #8
0
 private static void writeToIdDictionaryMethod(TextWriter writer, TableColumns tableColumns)
 {
     writer.WriteLine("public static Dictionary<" + tableColumns.KeyColumns.Single().DataTypeName + ", Row> ToIdDictionary( this IEnumerable<Row> rows ) {");
     writer.WriteLine(
         "return rows.ToDictionary( i => i." + EwlStatics.GetCSharpIdentifier(tableColumns.KeyColumns.Single().PascalCasedNameExceptForOracle) + " );");
     writer.WriteLine("}");
 }
예제 #9
0
        private static void writeGenericGetter(TextWriter writer, ModificationField field)
        {
            CodeGenerationStatics.AddSummaryDocComment(writer, getFormItemGetterSummary(field, "", new string[0]));

            var parameters = new List <CSharpParameter>();

            parameters.Add(new CSharpParameter("System.Func<{0},IReadOnlyCollection<FlowComponent>>".FormatWith(field.NullableTypeName), "contentGetter"));
            parameters.Add(new CSharpParameter("FormItemSetup", "setup", "null"));
            parameters.Add(new CSharpParameter("IReadOnlyCollection<PhrasingComponent>", "label", "null"));
            parameters.Add(
                new CSharpParameter(
                    field.TypeIs(typeof(string)) ? field.NullableTypeName : "SpecifiedValue<{0}>".FormatWith(field.NullableTypeName),
                    "value",
                    "null"));
            parameters.Add(new CSharpParameter("System.Func<System.Action<{0}>,EwfValidation>".FormatWith(field.TypeName), "validationGetter", "null"));

            writer.WriteLine(
                "public FormItem " + EwlStatics.GetCSharpIdentifier("Get" + field.PascalCasedName + "FormItem") + "( " +
                parameters.Select(i => i.MethodSignatureDeclaration).GetCommaDelimitedStringFromCollection() + " ) {");
            writer.WriteLine("label = label ?? \"{0}\".ToComponents();".FormatWith(getDefaultLabel(field)));
            writer.WriteLine(
                "return {0}.ToFormItem( setup: setup, label: label, validation: {1} );".FormatWith(
                    "contentGetter( {0} )".FormatWith(
                        field.TypeIs(typeof(string))
                                                        ? "value ?? {0}".FormatWith(EwlStatics.GetCSharpIdentifier(field.Name))
                                                        : "value != null ? value.Value : {0}".FormatWith(EwlStatics.GetCSharpIdentifier(field.Name))),
                    "validationGetter?.Invoke( v => {0} = v )".FormatWith(EwlStatics.GetCSharpIdentifier(field.Name))));
            writer.WriteLine("}");
        }
예제 #10
0
        internal static string GetNamespaceFromPath(string projectNamespace, string pathRelativeToProject, bool isFilePath)
        {
            var tokens          = pathRelativeToProject.Separate(Path.DirectorySeparatorChar.ToString(), false);
            var namespaceTokens = isFilePath ? tokens.Take(tokens.Count - 1) : tokens;

            return(projectNamespace + StringTools
                   .ConcatenateWithDelimiter(".", namespaceTokens.Select(i => EwlStatics.GetCSharpIdentifier(i.CapitalizeString())))
                   .PrependDelimiter("."));
        }
        private string getNamespaceFromFilePath(string projectNamespace, string filePathRelativeToProject)
        {
            var tokens = filePathRelativeToProject.Separate(System.IO.Path.DirectorySeparatorChar.ToString(), false);

            tokens = tokens.Take(tokens.Count - 1).ToList();
            return(StaticFileHandler.CombineNamespacesAndProcessEwfIfNecessary(
                       projectNamespace,
                       StringTools.ConcatenateWithDelimiter(".", tokens.Select(i => EwlStatics.GetCSharpIdentifier(i.CapitalizeString())).ToArray())));
        }
예제 #12
0
 private static void writeColumnProperty(TextWriter writer, Column column)
 {
     CodeGenerationStatics.AddSummaryDocComment(
         writer,
         "This object will " + (column.AllowsNull && !column.NullValueExpression.Any() ? "sometimes" : "never") + " be null.");
     writer.WriteLine(
         "public " + column.DataTypeName + " " + EwlStatics.GetCSharpIdentifier(column.PascalCasedNameExceptForOracle) + " { get { return __basicRow." +
         EwlStatics.GetCSharpIdentifier(column.PascalCasedName) + "; } }");
 }
예제 #13
0
        protected override void loadData()
        {
            var pb =
                PostBack.CreateFull(
                    actionGetter:
                    () =>
                    new PostBackAction(
                        new SecondaryResponse(
                            () =>
                            EwfResponse.Create(
                                ContentTypes.ApplicationZip,
                                new EwfResponseBodyCreator(createAndZipSystem),
                                fileNameCreator: () => "{0}.zip".FormatWith(systemShortName.Value)))));

            FormState.ExecuteWithDataModificationsAndDefaultAction(
                pb.ToCollection(),
                () => {
                ph.AddControlsReturnThis(
                    FormItemBlock.CreateFormItemTable(
                        formItems: new[]
                {
                    FormItem.Create(
                        "System name",
                        new EwfTextBox(""),
                        validationGetter: control => new EwfValidation(
                            (pbv, validator) => {
                        systemName.Value = validator.GetString(
                            new ValidationErrorHandler("system name"),
                            control.GetPostBackValue(pbv),
                            false,
                            50);
                        if (systemName.Value != systemName.Value.RemoveNonAlphanumericCharacters(preserveWhiteSpace: true))
                        {
                            validator.NoteErrorAndAddMessage("The system name must consist of only alphanumeric characters and white space.");
                        }
                        systemShortName.Value = systemName.Value.EnglishToPascal();
                    })),
                    FormItem.Create(
                        "Base namespace",
                        new EwfTextBox(""),
                        validationGetter: control => new EwfValidation(
                            (pbv, validator) => {
                        baseNamespace.Value = validator.GetString(
                            new ValidationErrorHandler("base namespace"),
                            control.GetPostBackValue(pbv),
                            false,
                            50);
                        if (baseNamespace.Value != EwlStatics.GetCSharpIdentifier(baseNamespace.Value))
                        {
                            validator.NoteErrorAndAddMessage("The base namespace must be a valid C# identifier.");
                        }
                    }))
                }));
            });

            EwfUiStatics.SetContentFootActions(new ActionButtonSetup("Create System", new PostBackButton(pb)));
        }
예제 #14
0
 private static void writeAddColumnModificationsMethod(IEnumerable <Column> nonIdentityColumns)
 {
     writer.WriteLine("private void addColumnModifications( InlineDbModificationCommand cmd ) {");
     foreach (var column in nonIdentityColumns)
     {
         writer.WriteLine("if( " + getColumnFieldName(column) + ".Changed )");
         var columnValueExpression = column.GetCommandColumnValueExpression(EwlStatics.GetCSharpIdentifier(column.PascalCasedNameExceptForOracle));
         writer.WriteLine("cmd.AddColumnModification( " + columnValueExpression + " );");
     }
     writer.WriteLine("}");
 }
        internal static void Generate(string rootPath, string nameSpace, TextWriter writer)
        {
            var cssClasses = new HashSet <string>();

            foreach (var fileInfo in new DirectoryInfo(rootPath).GetFiles("*.css", SearchOption.AllDirectories))
            {
                new FileReader(fileInfo.FullName).ExecuteInStreamReader(
                    delegate(StreamReader reader) {
                    // Remove comments and styles.
                    // NOTE: We need to find a way to also throw out media query expressions.
                    var text = reader.ReadToEnd().RemoveTextBetweenStrings("/*", "*/").RemoveTextBetweenStrings("{", "}");

                    foreach (Match match in Regex.Matches(text, @"\.(\w+)"))
                    {
                        cssClasses.Add(match.Groups[1].Value);
                    }
                });
            }

            if (cssClasses.Any())
            {
                writer.WriteLine("namespace " + nameSpace + " {");

                CodeGenerationStatics.AddSummaryDocComment(writer, "This class provides typesafe access to css classes present in *.css files.");
                writer.WriteLine("public class ElementClasses {");

                var identifiers = new HashSet <string>();
                foreach (var elementClass in cssClasses)
                {
                    writer.WriteLine("/// <summary>");
                    writer.WriteLine("/// Constant for the '{0}' class.".FormatWith(elementClass));
                    writer.WriteLine("/// </summary>");
                    var identifier = EwlStatics.GetCSharpIdentifier(elementClass.CapitalizeString());
                    if (identifiers.Contains(identifier))
                    {
                        var uniqueIdentifier = identifier;
                        var i = 0;
                        while (identifiers.Contains(uniqueIdentifier))
                        {
                            uniqueIdentifier = identifier + i++;
                        }
                        identifier = uniqueIdentifier;
                    }
                    identifiers.Add(identifier);
                    writer.WriteLine("public static readonly ElementClass {0} = new ElementClass( \"{1}\" );".FormatWith(identifier, elementClass));
                }

                writer.WriteLine("}");                   // class
                writer.WriteLine("}");                   // namespace
            }

            // Web Forms compatibility. Remove when EnduraCode goal 790 is complete.
            generateLegacy(rootPath, nameSpace, writer);
        }
 private static void writeGetColumnModificationValuesMethod(IEnumerable <Column> nonIdentityColumns)
 {
     writer.WriteLine("private IReadOnlyCollection<InlineDbCommandColumnValue> getColumnModificationValues() {");
     writer.WriteLine("var values = new List<InlineDbCommandColumnValue>();");
     foreach (var column in nonIdentityColumns)
     {
         writer.WriteLine("if( " + getColumnFieldName(column) + ".Changed )");
         writer.WriteLine(
             "values.Add( {0} );".FormatWith(
                 column.GetCommandColumnValueExpression(EwlStatics.GetCSharpIdentifier(column.PascalCasedNameExceptForOracle))));
     }
     writer.WriteLine("return values;");
     writer.WriteLine("}");
 }
        private static void writeFormItemGetter(
            TextWriter writer, ModificationField field, string controlTypeForName, IEnumerable <CSharpParameter> requiredParams, bool controlIsLabeled,
            IEnumerable <CSharpParameter> preValueOptionalParams, string valueParamTypeName, IEnumerable <CSharpParameter> postValueOptionalParams,
            bool includeAdditionalValidationMethodParam, Func <string, string> formControlExpressionGetter, string preFormItemStatements = "",
            string postFormItemStatements = "", IEnumerable <string> additionalSummarySentences = null)
        {
            var parameters = new List <CSharpParameter>();

            parameters.AddRange(requiredParams);
            parameters.Add(new CSharpParameter("FormItemSetup", "formItemSetup", "null"));
            parameters.Add(new CSharpParameter("IReadOnlyCollection<PhrasingComponent>", "label", "null"));
            if (controlIsLabeled)
            {
                parameters.Add(new CSharpParameter("IReadOnlyCollection<PhrasingComponent>", "formItemLabel", "null"));
            }
            parameters.AddRange(preValueOptionalParams);
            parameters.Add(new CSharpParameter(valueParamTypeName, "value", "null"));
            parameters.AddRange(postValueOptionalParams);
            if (includeAdditionalValidationMethodParam)
            {
                parameters.Add(
                    new CSharpParameter(
                        "System.Action<Validator>",
                        "additionalValidationMethod",
                        defaultValue: "null",
                        description: "A method that takes the form control’s validator and performs additional validation."));
            }

            CodeGenerationStatics.AddSummaryDocComment(
                writer,
                getFormItemGetterSummary(field, controlTypeForName, additionalSummarySentences ?? new string[0]));
            foreach (var i in parameters)
            {
                CodeGenerationStatics.AddParamDocComment(writer, i.Name, i.Description);
            }
            writer.WriteLine(
                "public FormItem " + EwlStatics.GetCSharpIdentifier("Get" + field.PascalCasedName + controlTypeForName + "FormItem") + "( " +
                parameters.Select(i => i.MethodSignatureDeclaration).GetCommaDelimitedStringFromCollection() + " ) {");
            writer.WriteLine("label = label ?? \"{0}\".ToComponents();".FormatWith(getDefaultLabel(field)));
            writer.WriteLine(
                StringTools.ConcatenateWithDelimiter(
                    Environment.NewLine,
                    preFormItemStatements,
                    "var formItem = {0}.ToFormItem( setup: formItemSetup, label: {1} );".FormatWith(
                        formControlExpressionGetter(EwlStatics.GetCSharpIdentifier(field.PrivateFieldName)),
                        controlIsLabeled ? "formItemLabel" : "label"),
                    postFormItemStatements,
                    "return formItem;"));
            writer.WriteLine("}");
        }
 internal static void WriteRevisionDeltaExtensionMethods(TextWriter writer, string retrievalClassName, IEnumerable <Column> columns)
 {
     foreach (var column in columns)
     {
         writer.WriteLine(
             "public static ValueDelta<{0}> Get{1}Delta( this RevisionDelta<{2}.Row> revisionDelta, string valueName = \"{3}\" ) {{".FormatWith(
                 column.DataTypeName,
                 column.PascalCasedName,
                 retrievalClassName,
                 column.PascalCasedName.CamelToEnglish()));
         writer.WriteLine(
             "return revisionDelta.GetValueDelta( valueName, i => i.{0} );".FormatWith(
                 EwlStatics.GetCSharpIdentifier(column.PascalCasedNameExceptForOracle)));
         writer.WriteLine("}");
     }
 }
예제 #19
0
        protected override void loadData()
        {
            FormState.ExecuteWithDataModificationsAndDefaultAction(
                PostBack.CreateFull(
                    actionGetter: () => new PostBackAction(
                        new PageReloadBehavior(
                            secondaryResponse: new SecondaryResponse(
                                () => EwfResponse.Create(
                                    ContentTypes.ApplicationZip,
                                    new EwfResponseBodyCreator(createAndZipSystem),
                                    fileNameCreator: () => "{0}.zip".FormatWith(systemShortName.Value))))))
                .ToCollection(),
                () => {
                ph.AddControlsReturnThis(
                    FormItemList.CreateStack(
                        items: new[]
                {
                    systemName.ToTextControl(
                        false,
                        value: "",
                        maxLength: 50,
                        additionalValidationMethod: validator => {
                        if (systemName.Value != systemName.Value.RemoveNonAlphanumericCharacters(preserveWhiteSpace: true))
                        {
                            validator.NoteErrorAndAddMessage("The system name must consist of only alphanumeric characters and white space.");
                        }
                        systemShortName.Value = systemName.Value.EnglishToPascal();
                    })
                    .ToFormItem(label: "System name".ToComponents()),
                    baseNamespace.ToTextControl(
                        false,
                        value: "",
                        maxLength: 50,
                        additionalValidationMethod: validator => {
                        if (baseNamespace.Value != EwlStatics.GetCSharpIdentifier(baseNamespace.Value))
                        {
                            validator.NoteErrorAndAddMessage("The base namespace must be a valid C# identifier.");
                        }
                    })
                    .ToFormItem(label: "Base namespace".ToComponents())
                })
                    .ToCollection()
                    .GetControls());

                EwfUiStatics.SetContentFootActions(new ButtonSetup("Create System").ToCollection());
            });
        }
예제 #20
0
        private static void writeInConditionClasses(DBConnection cn, TextWriter writer, string table)
        {
            writer.WriteLine("public static class " + EwlStatics.GetCSharpIdentifier(table.TableNameToPascal(cn) + "TableInConditions") + " {");
            foreach (var column in new TableColumns(cn, table, false).AllColumnsExceptRowVersion)
            {
                CodeGenerationStatics.AddSummaryDocComment(writer, "A condition that narrows the scope of a command.");
                writer.WriteLine("public class " + GetConditionClassName(column) + ": " + GetTableConditionInterfaceName(cn, table) + " {");
                writer.WriteLine("private readonly string subQuery;");

                CodeGenerationStatics.AddSummaryDocComment(writer, "Creates a condition to narrow the scope of a command.");
                writer.WriteLine("public " + GetConditionClassName(column) + "( string subQuery ) {");
                writer.WriteLine("this.subQuery = subQuery;");
                writer.WriteLine("}");

                writer.WriteLine("InlineDbCommandCondition TableCondition.CommandCondition { get { return new InCondition( \"" + column.Name + "\", subQuery ); } }");

                writer.WriteLine("}");
            }
            writer.WriteLine("}");
        }
예제 #21
0
        internal WebItemGeneralData(string projectPath, string projectNamespace, string pathRelativeToProject, bool includeFileExtensionInClassName)
        {
            this.pathRelativeToProject = pathRelativeToProject;
            var path = EwlStatics.CombinePaths(projectPath, pathRelativeToProject);

            fileName = Path.GetFileName(path);

            // Load this item's code if it exists.
            code = path.EndsWith(".cs") ? File.ReadAllText(path) : "";

            // Attempt to get the namespace from the code. If this fails, use a namespace based on the item's path in the project.
            foreach (Match match in Regex.Matches(code, @"namespace\s(?<namespace>.*)\s{"))
            {
                itemNamespace = match.Groups["namespace"].Value;
            }
            if (itemNamespace == null)
            {
                itemNamespace = GetNamespaceFromPath(projectNamespace, pathRelativeToProject, true);
            }

            className = EwlStatics.GetCSharpIdentifier(
                Path.GetFileNameWithoutExtension(path).CapitalizeString() + (includeFileExtensionInClassName ? Path.GetExtension(path).CapitalizeString() : ""));
        }
        internal static void Generate(
            DBConnection cn, TextWriter writer, string baseNamespace, Database database, Configuration.SystemDevelopment.Database configuration)
        {
            if (configuration.rowConstantTables == null)
            {
                return;
            }

            writer.WriteLine("namespace " + baseNamespace + "." + database.SecondaryDatabaseName + "RowConstants {");
            foreach (var table in configuration.rowConstantTables)
            {
                Column valueColumn;
                var    orderIsSpecified = !table.orderByColumn.IsNullOrWhiteSpace();
                var    values           = new List <string>();
                var    names            = new List <string>();
                try {
                    var columns = new TableColumns(cn, table.tableName, false);
                    valueColumn = columns.AllColumnsExceptRowVersion.Single(column => column.Name.ToLower() == table.valueColumn.ToLower());
                    var nameColumn = columns.AllColumnsExceptRowVersion.Single(column => column.Name.ToLower() == table.nameColumn.ToLower());

                    var cmd = new InlineSelect(
                        new[] { valueColumn.Name, nameColumn.Name },
                        "FROM " + table.tableName,
                        false,
                        orderByClause: orderIsSpecified ? "ORDER BY " + table.orderByColumn : "");
                    cmd.Execute(
                        cn,
                        reader => {
                        while (reader.Read())
                        {
                            if (reader.IsDBNull(reader.GetOrdinal(valueColumn.Name)))
                            {
                                values.Add(valueColumn.NullValueExpression.Any() ? valueColumn.NullValueExpression : "null");
                            }
                            else
                            {
                                var valueString = valueColumn.ConvertIncomingValue(reader[valueColumn.Name]).ToString();
                                values.Add(valueColumn.DataTypeName == typeof(string).ToString() ? "\"{0}\"".FormatWith(valueString) : valueString);
                            }
                            names.Add(nameColumn.ConvertIncomingValue(reader[nameColumn.Name]).ToString());
                        }
                    });
                }
                catch (Exception e) {
                    throw new UserCorrectableException(
                              "Column or data retrieval failed for the " + table.tableName + " row constant table. Make sure the table and the value, name, and order by columns exist.",
                              e);
                }

                CodeGenerationStatics.AddSummaryDocComment(writer, "Provides constants copied from the " + table.tableName + " table.");
                var className = table.tableName.TableNameToPascal(cn) + "Rows";
                writer.WriteLine("public class " + className + " {");

                // constants
                for (var i = 0; i < values.Count; i++)
                {
                    CodeGenerationStatics.AddSummaryDocComment(writer, "Constant generated from row in database table.");

                    // It's important that row constants actually *be* constants (instead of static readonly) so they can be used in switch statements.
                    writer.WriteLine(
                        "public const " + valueColumn.DataTypeName + " " + EwlStatics.GetCSharpIdentifier(names[i].CamelToEnglish().EnglishToPascal()) + " = " + values[i] +
                        ";");
                }

                // one to one map
                var dictionaryType = "OneToOneMap<" + valueColumn.DataTypeName + ", string>";
                writer.WriteLine("private static readonly " + dictionaryType + " " + dictionaryName + " = new " + dictionaryType + "();");

                writeStaticConstructor(writer, className, names, values, valueColumn.DataTypeName);

                // methods
                writeGetNameFromValueMethod(writer, valueColumn.DataTypeName);
                writeGetValueFromNameMethod(writer, valueColumn.DataTypeName);
                if (orderIsSpecified)
                {
                    writeGetValuesToNamesMethod(writer, valueColumn.DataTypeName);
                    writeFillListControlMethod(writer, valueColumn);
                }

                writer.WriteLine("}");           // class
            }
            writer.WriteLine("}");               // namespace
        }
예제 #23
0
 internal static string GetClassName(DBConnection cn, string table)
 {
     return(EwlStatics.GetCSharpIdentifier(table.TableNameToPascal(cn) + "TableRetrieval"));
 }
        void IHttpHandler.ProcessRequest(HttpContext context)
        {
            var url = EwfApp.GetRequestAppRelativeUrl(context.Request);

            var queryIndex = url.IndexOf("?", StringComparison.Ordinal);

            if (queryIndex >= 0)
            {
                url = url.Remove(queryIndex);
            }

            var extensionIndex = url.LastIndexOf(".", StringComparison.Ordinal);

            var versionStringOrFileExtensionIndex = extensionIndex;
            var urlVersionString = "";

            if (url.StartsWith(VersionedFilesFolderName + "/") || url.StartsWith(EwfFolderName + "/" + VersionedFilesFolderName + "/"))
            {
                urlVersionString = "invariant";
            }
            else
            {
                // We assume that all URL version strings will have the same length as the format string.
                var prefixedVersionStringIndex = extensionIndex - (urlVersionStringPrefix.Length + EwfSafeResponseWriter.UrlVersionStringFormat.Length);

                if (prefixedVersionStringIndex >= 0)
                {
                    DateTimeOffset dateAndTime;
                    var            versionString = url.Substring(prefixedVersionStringIndex + urlVersionStringPrefix.Length, EwfSafeResponseWriter.UrlVersionStringFormat.Length);
                    if (DateTimeOffset.TryParseExact(
                            versionString,
                            EwfSafeResponseWriter.UrlVersionStringFormat,
                            DateTimeFormatInfo.InvariantInfo,
                            DateTimeStyles.None,
                            out dateAndTime))
                    {
                        versionStringOrFileExtensionIndex = prefixedVersionStringIndex;
                        urlVersionString = versionString;
                    }
                }
            }

            if (versionStringOrFileExtensionIndex < 0)
            {
                throw new ResourceNotAvailableException("Failed to find the extension in the URL.", null);
            }
            var extension      = url.Substring(extensionIndex);
            var staticFileInfo =
                EwfApp.GlobalType.Assembly.CreateInstance(
                    CombineNamespacesAndProcessEwfIfNecessary(
                        EwfApp.GlobalType.Namespace,
                        (url.Remove(versionStringOrFileExtensionIndex) + extension.CapitalizeString()).Separate("/", false)
                        .Select(i => EwlStatics.GetCSharpIdentifier(i.CapitalizeString()))
                        .Aggregate((a, b) => a + "." + b) + "+Info")) as StaticFileInfo;

            if (staticFileInfo == null)
            {
                throw new ResourceNotAvailableException("Failed to create an Info object for the request.", null);
            }

            var mediaTypeOverride = EwfApp.Instance.GetMediaTypeOverrides().SingleOrDefault(i => i.FileExtension == extension);
            var contentType       = mediaTypeOverride != null ? mediaTypeOverride.MediaType : MimeTypeMap.GetMimeType(extension);

            Func <string>         cacheKeyGetter = () => staticFileInfo.GetUrl(false, false, false);
            EwfSafeResponseWriter responseWriter;

            if (contentType == ContentTypes.Css)
            {
                Func <string> cssGetter = () => File.ReadAllText(staticFileInfo.FilePath);
                responseWriter = urlVersionString.Any()
                                                         ? new EwfSafeResponseWriter(
                    cssGetter,
                    urlVersionString,
                    () => new ResponseMemoryCachingSetup(cacheKeyGetter(), staticFileInfo.GetResourceLastModificationDateAndTime()))
                                                         : new EwfSafeResponseWriter(
                    () => EwfResponse.Create(ContentTypes.Css, new EwfResponseBodyCreator(() => CssPreprocessor.TransformCssFile(cssGetter()))),
                    staticFileInfo.GetResourceLastModificationDateAndTime(),
                    memoryCacheKeyGetter: cacheKeyGetter);
            }
            else
            {
                Func <EwfResponse> responseCreator = () => EwfResponse.Create(
                    contentType,
                    new EwfResponseBodyCreator(
                        responseStream => {
                    using (var fileStream = File.OpenRead(staticFileInfo.FilePath))
                        fileStream.CopyTo(responseStream);
                }));
                responseWriter = urlVersionString.Any()
                                                         ? new EwfSafeResponseWriter(
                    responseCreator,
                    urlVersionString,
                    memoryCachingSetupGetter:
                    () => new ResponseMemoryCachingSetup(cacheKeyGetter(), staticFileInfo.GetResourceLastModificationDateAndTime()))
                                                         : new EwfSafeResponseWriter(
                    responseCreator,
                    staticFileInfo.GetResourceLastModificationDateAndTime(),
                    memoryCacheKeyGetter: cacheKeyGetter);
            }
            responseWriter.WriteResponse();
        }
예제 #25
0
        private void generateLibraryCode(DevelopmentInstallation installation)
        {
            var libraryGeneratedCodeFolderPath = EwlStatics.CombinePaths(installation.DevelopmentInstallationLogic.LibraryPath, "Generated Code");

            Directory.CreateDirectory(libraryGeneratedCodeFolderPath);
            var isuFilePath = EwlStatics.CombinePaths(libraryGeneratedCodeFolderPath, "ISU.cs");

            IoMethods.DeleteFile(isuFilePath);
            using (TextWriter writer = new StreamWriter(isuFilePath)) {
                // Don't add "using System" here. It will create a huge number of ReSharper warnings in the generated code file.
                writer.WriteLine("using System.Collections.Generic;");
                writer.WriteLine("using System.Data;");                   // Necessary for stored procedure logic
                writer.WriteLine("using System.Data.Common;");
                writer.WriteLine("using System.Diagnostics;");            // Necessary for ServerSideConsoleAppStatics
                writer.WriteLine("using System.Linq;");
                writer.WriteLine("using System.Reflection;");
                writer.WriteLine("using System.Runtime.InteropServices;");
                writer.WriteLine("using System.Web.UI;");
                writer.WriteLine("using System.Web.UI.WebControls;");
                writer.WriteLine("using EnterpriseWebLibrary;");
                writer.WriteLine("using EnterpriseWebLibrary.Caching;");
                writer.WriteLine("using EnterpriseWebLibrary.Collections;");                   // Necessary for row constants
                writer.WriteLine("using EnterpriseWebLibrary.Configuration;");
                writer.WriteLine("using EnterpriseWebLibrary.DataAccess;");
                writer.WriteLine("using EnterpriseWebLibrary.DataAccess.CommandWriting;");
                writer.WriteLine("using EnterpriseWebLibrary.DataAccess.CommandWriting.Commands;");
                writer.WriteLine("using EnterpriseWebLibrary.DataAccess.CommandWriting.InlineConditionAbstraction;");
                writer.WriteLine("using EnterpriseWebLibrary.DataAccess.CommandWriting.InlineConditionAbstraction.Conditions;");
                writer.WriteLine("using EnterpriseWebLibrary.DataAccess.RetrievalCaching;");
                writer.WriteLine("using EnterpriseWebLibrary.DataAccess.RevisionHistory;");
                writer.WriteLine("using EnterpriseWebLibrary.DataAccess.StandardModification;");
                writer.WriteLine("using EnterpriseWebLibrary.Email;");
                writer.WriteLine("using EnterpriseWebLibrary.EnterpriseWebFramework;");
                writer.WriteLine("using EnterpriseWebLibrary.EnterpriseWebFramework.Controls;");
                writer.WriteLine("using EnterpriseWebLibrary.InputValidation;");

                writer.WriteLine();
                writeAssemblyInfo(writer, installation, "Library");
                writer.WriteLine();
                var recognizedInstallation = installation as RecognizedDevelopmentInstallation;
                if (ConfigurationLogic.SystemProviderExists && !installation.DevelopmentInstallationLogic.SystemIsEwl &&
                    (recognizedInstallation == null || !recognizedInstallation.SystemIsEwlCacheCoordinator))
                {
                    generateGeneralProvider(writer, installation);
                }
                if (installation.ExistingInstallationLogic.RuntimeConfiguration.WebApplications.Any())
                {
                    writer.WriteLine();
                    writer.WriteLine("namespace " + installation.DevelopmentInstallationLogic.DevelopmentConfiguration.LibraryNamespaceAndAssemblyName + " {");
                    writer.WriteLine("public static class WebApplicationNames {");
                    foreach (var i in installation.ExistingInstallationLogic.RuntimeConfiguration.WebApplications)
                    {
                        writer.WriteLine("public const string {0} = \"{1}\";".FormatWith(EwlStatics.GetCSharpIdentifier(i.Name.EnglishToPascal()), i.Name));
                    }
                    writer.WriteLine("}");
                    writer.WriteLine("}");
                }
                writer.WriteLine();
                TypedCssClassStatics.Generate(
                    installation.GeneralLogic.Path,
                    installation.DevelopmentInstallationLogic.DevelopmentConfiguration.LibraryNamespaceAndAssemblyName,
                    writer);
                writer.WriteLine();
                generateServerSideConsoleAppStatics(writer, installation);
                generateDataAccessCode(writer, installation);

                var emailTemplateFolderPath = EwlStatics.CombinePaths(
                    InstallationFileStatics.GetGeneralFilesFolderPath(installation.GeneralLogic.Path, true),
                    InstallationFileStatics.FilesFolderName,
                    EmailTemplate.TemplateFolderName);
                if (Directory.Exists(emailTemplateFolderPath))
                {
                    writer.WriteLine();
                    writer.WriteLine("namespace " + installation.DevelopmentInstallationLogic.DevelopmentConfiguration.LibraryNamespaceAndAssemblyName + " {");
                    writer.WriteLine("public static class EmailTemplates {");
                    foreach (var i in IoMethods.GetFileNamesInFolder(emailTemplateFolderPath, searchPattern: "*.html"))
                    {
                        writer.WriteLine(
                            "public static readonly EmailTemplateName {0} = new EmailTemplateName( \"{1}\" );".FormatWith(
                                EwlStatics.GetCSharpIdentifier(Path.GetFileNameWithoutExtension(i).EnglishToPascal()),
                                i));
                    }
                    writer.WriteLine("}");
                    writer.WriteLine("}");
                }
            }
        }
예제 #26
0
        internal static void Generate(
            DBConnection cn, TextWriter writer, string namespaceDeclaration, Database database, IEnumerable <string> tableNames,
            Configuration.SystemDevelopment.Database configuration)
        {
            writer.WriteLine(namespaceDeclaration);
            foreach (var table in tableNames)
            {
                CodeGenerationStatics.AddSummaryDocComment(writer, "Contains logic that retrieves rows from the " + table + " table.");
                writer.WriteLine("public static partial class " + GetClassName(cn, table) + " {");

                var isRevisionHistoryTable = DataAccessStatics.IsRevisionHistoryTable(table, configuration);
                var columns = new TableColumns(cn, table, isRevisionHistoryTable);

                // Write nested classes.
                DataAccessStatics.WriteRowClasses(
                    writer,
                    columns.AllColumns,
                    localWriter => {
                    if (!isRevisionHistoryTable)
                    {
                        return;
                    }
                    writer.WriteLine(
                        "public UserTransaction Transaction { get { return RevisionHistoryStatics.UserTransactionsById[ RevisionHistoryStatics.RevisionsById[ System.Convert.ToInt32( " +
                        EwlStatics.GetCSharpIdentifier(columns.PrimaryKeyAndRevisionIdColumn.PascalCasedNameExceptForOracle) + " ) ].UserTransactionId ]; } }");
                },
                    localWriter => {
                    if (!columns.DataColumns.Any())
                    {
                        return;
                    }

                    var modClass = database.SecondaryDatabaseName + "Modification." +
                                   StandardModificationStatics.GetClassName(cn, table, isRevisionHistoryTable, isRevisionHistoryTable);
                    var revisionHistorySuffix = StandardModificationStatics.GetRevisionHistorySuffix(isRevisionHistoryTable);
                    writer.WriteLine("public " + modClass + " ToModification" + revisionHistorySuffix + "() {");
                    writer.WriteLine(
                        "return " + modClass + ".CreateForSingleRowUpdate" + revisionHistorySuffix + "( " +
                        StringTools.ConcatenateWithDelimiter(
                            ", ",
                            columns.AllColumnsExceptRowVersion.Select(i => EwlStatics.GetCSharpIdentifier(i.PascalCasedNameExceptForOracle)).ToArray()) + " );");
                    writer.WriteLine("}");
                });
                writeCacheClass(cn, writer, database, table, columns, isRevisionHistoryTable);

                var isSmallTable = configuration.SmallTables != null && configuration.SmallTables.Any(i => i.EqualsIgnoreCase(table));

                var tableUsesRowVersionedCaching = configuration.TablesUsingRowVersionedDataCaching != null &&
                                                   configuration.TablesUsingRowVersionedDataCaching.Any(i => i.EqualsIgnoreCase(table));
                if (tableUsesRowVersionedCaching && columns.RowVersionColumn == null && !(cn.DatabaseInfo is OracleInfo))
                {
                    throw new UserCorrectableException(
                              cn.DatabaseInfo is MySqlInfo
                                                        ? "Row-versioned data caching cannot currently be used with MySQL databases."
                                                        : "Row-versioned data caching can only be used with the {0} table if you add a rowversion column.".FormatWith(table));
                }

                if (isSmallTable)
                {
                    writeGetAllRowsMethod(writer, isRevisionHistoryTable, false);
                }
                writeGetRowsMethod(cn, writer, database, table, columns, isSmallTable, tableUsesRowVersionedCaching, isRevisionHistoryTable, false);
                if (isRevisionHistoryTable)
                {
                    if (isSmallTable)
                    {
                        writeGetAllRowsMethod(writer, true, true);
                    }
                    writeGetRowsMethod(cn, writer, database, table, columns, isSmallTable, tableUsesRowVersionedCaching, true, true);
                }

                writeGetRowMatchingPkMethod(cn, writer, database, table, columns, isSmallTable, tableUsesRowVersionedCaching, isRevisionHistoryTable);

                if (isRevisionHistoryTable)
                {
                    DataAccessStatics.WriteGetLatestRevisionsConditionMethod(writer, columns.PrimaryKeyAndRevisionIdColumn.Name);
                }

                if (tableUsesRowVersionedCaching)
                {
                    var keyTupleTypeArguments = getPkAndVersionTupleTypeArguments(cn, columns);

                    writer.WriteLine("private static " + "Cache<System.Tuple<" + keyTupleTypeArguments + ">, BasicRow>" + " getRowsByPkAndVersion() {");
                    writer.WriteLine(
                        "return AppMemoryCache.GetCacheValue<{0}>( \"{1}\", () => new {0}( i => System.Tuple.Create( {2} ) ) ).RowsByPkAndVersion;".FormatWith(
                            "VersionedRowDataCache<System.Tuple<{0}>, System.Tuple<{1}>, BasicRow>".FormatWith(getPkTupleTypeArguments(columns), keyTupleTypeArguments),
                            database.SecondaryDatabaseName + table.TableNameToPascal(cn) + "TableRetrievalRowsByPkAndVersion",
                            StringTools.ConcatenateWithDelimiter(", ", Enumerable.Range(1, columns.KeyColumns.Count()).Select(i => "i.Item{0}".FormatWith(i)).ToArray())));
                    writer.WriteLine("}");
                }

                // Initially we did not generate this method for small tables, but we found a need for it when the cache is disabled since that will cause
                // GetRowMatchingId to repeatedly query.
                if (columns.KeyColumns.Count() == 1 && columns.KeyColumns.Single().Name.ToLower().EndsWith("id"))
                {
                    writeToIdDictionaryMethod(writer, columns);
                }

                if (isRevisionHistoryTable)
                {
                    DataAccessStatics.WriteRevisionDeltaExtensionMethods(writer, GetClassName(cn, table), columns.DataColumns);
                }

                writer.WriteLine("}");           // class
            }
            writer.WriteLine("}");               // namespace
        }
 private static string getColumnFieldName(Column column)
 {
     return(EwlStatics.GetCSharpIdentifier(column.CamelCasedName + "ColumnValue"));
 }
예제 #28
0
        private static void writeResultSetCreatorBody(
            DBConnection cn, TextWriter writer, Database database, string table, TableColumns tableColumns, bool tableUsesRowVersionedCaching,
            bool excludesPreviousRevisions, string cacheQueryInDbExpression)
        {
            if (tableUsesRowVersionedCaching)
            {
                writer.WriteLine("var results = new List<Row>();");
                writer.WriteLine(DataAccessStatics.GetConnectionExpression(database) + ".ExecuteInTransaction( delegate {");

                // Query for the cache keys of the results.
                writer.WriteLine(
                    "var keyCommand = {0};".FormatWith(
                        getInlineSelectExpression(
                            table,
                            tableColumns,
                            "{0}, \"{1}\"".FormatWith(
                                StringTools.ConcatenateWithDelimiter(", ", tableColumns.KeyColumns.Select(i => "\"{0}\"".FormatWith(i.Name)).ToArray()),
                                cn.DatabaseInfo is OracleInfo ? "ORA_ROWSCN" : tableColumns.RowVersionColumn.Name),
                            cacheQueryInDbExpression)));
                writer.WriteLine(getCommandConditionAddingStatement("keyCommand"));
                writer.WriteLine("var keys = new List<System.Tuple<{0}>>();".FormatWith(getPkAndVersionTupleTypeArguments(cn, tableColumns)));
                writer.WriteLine(
                    "keyCommand.Execute( " + DataAccessStatics.GetConnectionExpression(database) + ", r => { while( r.Read() ) keys.Add( " +
                    "System.Tuple.Create( {0}, {1} )".FormatWith(
                        StringTools.ConcatenateWithDelimiter(
                            ", ",
                            tableColumns.KeyColumns.Select((c, i) => c.GetDataReaderValueExpression("r", ordinalOverride: i)).ToArray()),
                        cn.DatabaseInfo is OracleInfo
                                                        ? "({0})r.GetValue( {1} )".FormatWith(oracleRowVersionDataType, tableColumns.KeyColumns.Count())
                                                        : tableColumns.RowVersionColumn.GetDataReaderValueExpression("r", ordinalOverride: tableColumns.KeyColumns.Count())) + " ); } );");

                writer.WriteLine("var rowsByPkAndVersion = getRowsByPkAndVersion();");
                writer.WriteLine("var cachedKeyCount = keys.Where( i => rowsByPkAndVersion.ContainsKey( i ) ).Count();");

                // If all but a few results are cached, execute a single-row query for each missing result.
                writer.WriteLine("if( cachedKeyCount >= keys.Count() - 1 || cachedKeyCount >= keys.Count() * .99 ) {");
                writer.WriteLine("foreach( var key in keys ) {");
                writer.WriteLine("results.Add( new Row( rowsByPkAndVersion.GetOrAdd( key, () => {");
                writer.WriteLine("var singleRowCommand = {0};".FormatWith(getInlineSelectExpression(table, tableColumns, "\"*\"", "false")));
                foreach (var i in tableColumns.KeyColumns.Select((c, i) => new { column = c, index = i }))
                {
                    writer.WriteLine(
                        "singleRowCommand.AddCondition( ( ({0})new {1}( key.Item{2} ) ).CommandCondition );".FormatWith(
                            DataAccessStatics.GetTableConditionInterfaceName(cn, database, table),
                            DataAccessStatics.GetEqualityConditionClassName(cn, database, table, i.column),
                            i.index + 1));
                }
                writer.WriteLine("var singleRowResults = new List<BasicRow>();");
                writer.WriteLine(
                    "singleRowCommand.Execute( " + DataAccessStatics.GetConnectionExpression(database) +
                    ", r => { while( r.Read() ) singleRowResults.Add( new BasicRow( r ) ); } );");
                writer.WriteLine("return singleRowResults.Single();");
                writer.WriteLine("} ) ) );");
                writer.WriteLine("}");
                writer.WriteLine("}");

                // Otherwise, execute the full query.
                writer.WriteLine("else {");
                writer.WriteLine(
                    "var command = {0};".FormatWith(
                        getInlineSelectExpression(
                            table,
                            tableColumns,
                            cn.DatabaseInfo is OracleInfo ? "\"{0}.*\", \"ORA_ROWSCN\"".FormatWith(table) : "\"*\"",
                            cacheQueryInDbExpression)));
                writer.WriteLine(getCommandConditionAddingStatement("command"));
                writer.WriteLine("command.Execute( " + DataAccessStatics.GetConnectionExpression(database) + ", r => {");
                writer.WriteLine(
                    "while( r.Read() ) results.Add( new Row( rowsByPkAndVersion.GetOrAdd( System.Tuple.Create( {0}, {1} ), () => new BasicRow( r ) ) ) );".FormatWith(
                        StringTools.ConcatenateWithDelimiter(", ", tableColumns.KeyColumns.Select(i => i.GetDataReaderValueExpression("r")).ToArray()),
                        cn.DatabaseInfo is OracleInfo
                                                        ? "({0})r.GetValue( {1} )".FormatWith(oracleRowVersionDataType, tableColumns.AllColumns.Count())
                                                        : tableColumns.RowVersionColumn.GetDataReaderValueExpression("r")));
                writer.WriteLine("} );");
                writer.WriteLine("}");

                writer.WriteLine("} );");
            }
            else
            {
                writer.WriteLine("var command = {0};".FormatWith(getInlineSelectExpression(table, tableColumns, "\"*\"", cacheQueryInDbExpression)));
                writer.WriteLine(getCommandConditionAddingStatement("command"));
                writer.WriteLine("var results = new List<Row>();");
                writer.WriteLine(
                    "command.Execute( " + DataAccessStatics.GetConnectionExpression(database) +
                    ", r => { while( r.Read() ) results.Add( new Row( new BasicRow( r ) ) ); } );");
            }

            // Add all results to RowsByPk.
            writer.WriteLine("foreach( var i in results ) {");
            var pkTupleCreationArgs = tableColumns.KeyColumns.Select(i => "i." + EwlStatics.GetCSharpIdentifier(i.PascalCasedNameExceptForOracle));
            var pkTuple             = "System.Tuple.Create( " + StringTools.ConcatenateWithDelimiter(", ", pkTupleCreationArgs.ToArray()) + " )";

            writer.WriteLine("cache.RowsByPk[ " + pkTuple + " ] = i;");
            if (excludesPreviousRevisions)
            {
                writer.WriteLine("cache.LatestRevisionRowsByPk[ " + pkTuple + " ] = i;");
            }
            writer.WriteLine("}");

            writer.WriteLine("return results;");
        }
        private static void writeExecuteInsertOrUpdateMethod(
            DBConnection cn, string tableName, bool isRevisionHistoryClass, IEnumerable <Column> keyColumns, Column identityColumn)
        {
            writer.WriteLine("private void executeInsertOrUpdate( bool isLongRunning ) {");
            writer.WriteLine("try {");
            if (isRevisionHistoryClass)
            {
                writer.WriteLine(DataAccessStatics.GetConnectionExpression(database) + ".ExecuteInTransaction( delegate {");
            }


            // insert

            writer.WriteLine("if( modType == ModificationType.Insert ) {");

            // If this is a revision history table, write code to insert a new revision when a row is inserted into this table.
            if (isRevisionHistoryClass)
            {
                writer.WriteLine("var revisionHistorySetup = RevisionHistoryStatics.SystemProvider;");
                writer.WriteLine(getColumnFieldName(columns.PrimaryKeyAndRevisionIdColumn) + ".Value = revisionHistorySetup.GetNextMainSequenceValue();");
                writer.WriteLine(
                    "revisionHistorySetup.InsertRevision( System.Convert.ToInt32( " + getColumnFieldName(columns.PrimaryKeyAndRevisionIdColumn) +
                    ".Value ), System.Convert.ToInt32( " + getColumnFieldName(columns.PrimaryKeyAndRevisionIdColumn) + ".Value ), " +
                    DataAccessStatics.GetConnectionExpression(database) + ".GetUserTransactionId() );");
            }

            writer.WriteLine("var insert = new InlineInsert( \"" + tableName + "\" );");
            writer.WriteLine("insert.AddColumnModifications( getColumnModificationValues() );");
            if (identityColumn != null)
            {
                // One reason the ChangeType call is necessary: SQL Server identities always come back as decimal, and you can't cast a boxed decimal to an int.
                writer.WriteLine(
                    "{0}.Value = {1};".FormatWith(
                        getColumnFieldName(identityColumn),
                        identityColumn.GetIncomingValueConversionExpression(
                            "EwlStatics.ChangeType( insert.Execute( {0}, isLongRunning: isLongRunning ), typeof( {1} ) )".FormatWith(
                                DataAccessStatics.GetConnectionExpression(database),
                                identityColumn.UnconvertedDataTypeName))));
            }
            else
            {
                writer.WriteLine("insert.Execute( {0}, isLongRunning: isLongRunning );".FormatWith(DataAccessStatics.GetConnectionExpression(database)));
            }

            // Future calls to Execute should perform updates, not inserts. Use the values of key columns as conditions.
            writer.WriteLine("modType = ModificationType.Update;");
            writer.WriteLine("conditions = new List<" + DataAccessStatics.GetTableConditionInterfaceName(cn, database, tableName) + ">();");
            foreach (var column in keyColumns)
            {
                writer.WriteLine(
                    "conditions.Add( new " + DataAccessStatics.GetEqualityConditionClassName(cn, database, tableName, column) + "( " +
                    EwlStatics.GetCSharpIdentifier(column.PascalCasedNameExceptForOracle) + " ) );");
            }

            writer.WriteLine("}");               // if insert


            // update
            writer.WriteLine("else {");
            writer.WriteLine("var modificationValues = getColumnModificationValues();");
            writer.WriteLine("if( modificationValues.Any() ) {");
            if (isRevisionHistoryClass)
            {
                writer.WriteLine("copyLatestRevisions( conditions, isLongRunning );");
            }
            writer.WriteLine("var update = new InlineUpdate( \"" + tableName + "\" );");
            writer.WriteLine("update.AddColumnModifications( modificationValues );");
            writer.WriteLine("conditions.ForEach( condition => update.AddCondition( condition.CommandCondition ) );");
            if (isRevisionHistoryClass)
            {
                writer.WriteLine("update.AddCondition( getLatestRevisionsCondition() );");
            }
            writer.WriteLine("update.Execute( {0}, isLongRunning: isLongRunning );".FormatWith(DataAccessStatics.GetConnectionExpression(database)));
            writer.WriteLine("}");
            writer.WriteLine("}");               // else

            if (isRevisionHistoryClass)
            {
                writer.WriteLine("} );");        // cn.ExecuteInTransaction
            }
            writer.WriteLine("}");               // try

            writer.WriteLine("catch( System.Exception e ) {");
            writer.WriteLine("rethrowAsDataModificationExceptionIfNecessary( e );");
            writer.WriteLine("throw;");
            writer.WriteLine("}");               // catch

            writer.WriteLine("}");               // method
        }
 private static void writeColumnValueAssignmentsFromParameters(IEnumerable <Column> columns, string modObjectName)
 {
     foreach (var column in columns)
     {
         writer.WriteLine(modObjectName + "." + getColumnFieldName(column) + ".Value = " + EwlStatics.GetCSharpIdentifier(column.CamelCasedName) + ";");
     }
 }