internal static void Generate(DBConnection cn, TextWriter writer, string namespaceDeclaration, IDatabase database, IEnumerable <Table> tables, Database configuration)
        {
            writer.WriteLine(namespaceDeclaration);
            foreach (var table in tables)
            {
                try {
                    CodeGenerationStatics.AddSummaryDocComment(writer, "Contains logic that retrieves rows from the " + table + " table.");
                    writer.WrapInTableNamespaceIfNecessary(
                        table,
                        () => {
                        writer.WriteLine($"public static partial class {table.GetTableRetrievalClassDeclaration()} {{");

                        var isRevisionHistoryTable = DataAccessStatics.IsRevisionHistoryTable(table.Name, configuration);
                        var columns = new TableColumns(cn, table.ObjectIdentifier, 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( " +
                                Utility.GetCSharpIdentifier(columns.PrimaryKeyAndRevisionIdColumn.PascalCasedNameExceptForOracle) + " ) ].UserTransactionId ]; } }");
                        },
                            localWriter => {
                            if (!columns.DataColumns.Any())
                            {
                                return;
                            }

                            var modClass = "Modification." + table.GetStandardModificationClassReference();
                            var revisionHistorySuffix = StandardModificationStatics.GetRevisionHistorySuffix(isRevisionHistoryTable);
                            writer.WriteLine("public " + modClass + " ToModification" + revisionHistorySuffix + "() {");
                            writer.WriteLine(
                                "return " + modClass + ".CreateForSingleRowUpdate" + revisionHistorySuffix + "( " + StringTools.ConcatenateWithDelimiter(
                                    ", ",
                                    columns.AllColumnsExceptRowVersion.Select(i => Utility.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.ObjectIdentifier));

                        var tableUsesRowVersionedCaching = configuration.TablesUsingRowVersionedDataCaching != null &&
                                                           configuration.TablesUsingRowVersionedDataCaching.Any(i => i.EqualsIgnoreCase(table.ObjectIdentifier));
                        if (tableUsesRowVersionedCaching && columns.RowVersionColumn == null && !(cn.DatabaseInfo is OracleInfo))
                        {
                            throw new ApplicationException(
                                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,
                            configuration.CommandTimeoutSecondsTyped);
                        if (isRevisionHistoryTable)
                        {
                            if (isSmallTable)
                            {
                                writeGetAllRowsMethod(writer, true, true);
                            }
                            writeGetRowsMethod(
                                cn,
                                writer,
                                database,
                                table,
                                columns,
                                isSmallTable,
                                tableUsesRowVersionedCaching,
                                true,
                                true,
                                configuration.CommandTimeoutSecondsTyped);
                        }

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

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

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

                            writer.WriteLine($"private static Cache<{TypeNames.Tuple}<{keyTupleTypeArguments}>, BasicRow> getRowsByPkAndVersion() {{");
                            var first  = $"VersionedRowDataCache<{TypeNames.Tuple}<{getPkTupleTypeArguments( columns )}>, {TypeNames.Tuple}<{keyTupleTypeArguments}>, BasicRow>";
                            var second = table.Name.TableNameToPascal(cn) + "TableRetrievalRowsByPkAndVersion";
                            var third  = StringTools.ConcatenateWithDelimiter(", ", Enumerable.Range(1, columns.KeyColumns.Count()).Select(i => "i.Item{0}".FormatWith(i)));
                            writer.WriteLine(
                                $@"return AppMemoryCache.GetCacheValue<{first}>( ""{second}"", () => new {first}( i => {TypeNames.Tuple}.Create( {third} ) ) ).RowsByPkAndVersion;");
                            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);
                        }

                        writer.WriteLine("}");                                   // class
                    });
                }
                catch (Exception e) when(!(e is UserCorrectableException))
                {
                    throw new ApplicationException($"An error occurred while generating TableRetrieval logic for the '{table}' table.", e);
                }
            }

            writer.WriteLine("}");               // namespace
        }
Пример #2
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
        }