174 lines
6.0 KiB
C#
174 lines
6.0 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Data;
|
|
using System.Data.SqlClient;
|
|
using System.Reflection;
|
|
using Microsoft.Extensions.CommandLineUtils;
|
|
using Microsoft.Extensions.Tools.Internal;
|
|
|
|
namespace Microsoft.Extensions.Caching.SqlConfig.Tools
|
|
{
|
|
public class Program
|
|
{
|
|
private string _connectionString = null;
|
|
private string _schemaName = null;
|
|
private string _tableName = null;
|
|
private readonly IConsole _console;
|
|
|
|
public Program(IConsole console)
|
|
{
|
|
Ensure.NotNull(console, nameof(console));
|
|
|
|
_console = console;
|
|
}
|
|
|
|
public static int Main(string[] args)
|
|
{
|
|
return new Program(PhysicalConsole.Singleton).Run(args);
|
|
}
|
|
|
|
public int Run(string[] args)
|
|
{
|
|
DebugHelper.HandleDebugSwitch(ref args);
|
|
|
|
try
|
|
{
|
|
var app = new CommandLineApplication
|
|
{
|
|
Name = "dotnet sql-cache",
|
|
FullName = "SQL Server Cache Command Line Tool",
|
|
Description =
|
|
"Creates table and indexes in Microsoft SQL Server database to be used for distributed caching",
|
|
};
|
|
|
|
app.HelpOption();
|
|
app.VersionOptionFromAssemblyAttributes(typeof(Program).GetTypeInfo().Assembly);
|
|
var verbose = app.VerboseOption();
|
|
|
|
app.Command("create", command =>
|
|
{
|
|
command.Description = app.Description;
|
|
|
|
var connectionStringArg = command.Argument(
|
|
"[connectionString]", "The connection string to connect to the database.");
|
|
|
|
var schemaNameArg = command.Argument(
|
|
"[schemaName]", "Name of the table schema.");
|
|
|
|
var tableNameArg = command.Argument(
|
|
"[tableName]", "Name of the table to be created.");
|
|
|
|
command.HelpOption();
|
|
|
|
command.OnExecute(() =>
|
|
{
|
|
var reporter = CreateReporter(verbose.HasValue());
|
|
if (string.IsNullOrEmpty(connectionStringArg.Value)
|
|
|| string.IsNullOrEmpty(schemaNameArg.Value)
|
|
|| string.IsNullOrEmpty(tableNameArg.Value))
|
|
{
|
|
reporter.Error("Invalid input");
|
|
app.ShowHelp();
|
|
return 2;
|
|
}
|
|
|
|
_connectionString = connectionStringArg.Value;
|
|
_schemaName = schemaNameArg.Value;
|
|
_tableName = tableNameArg.Value;
|
|
|
|
return CreateTableAndIndexes(reporter);
|
|
});
|
|
});
|
|
|
|
// Show help information if no subcommand/option was specified.
|
|
app.OnExecute(() =>
|
|
{
|
|
app.ShowHelp();
|
|
return 2;
|
|
});
|
|
|
|
return app.Execute(args);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
CreateReporter(verbose: false).Error($"An error occurred. {exception.Message}");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
private IReporter CreateReporter(bool verbose)
|
|
=> new ConsoleReporter(_console, verbose, quiet: false);
|
|
private int CreateTableAndIndexes(IReporter reporter)
|
|
{
|
|
ValidateConnectionString();
|
|
|
|
using (var connection = new SqlConnection(_connectionString))
|
|
{
|
|
connection.Open();
|
|
|
|
var sqlQueries = new SqlQueries(_schemaName, _tableName);
|
|
var command = new SqlCommand(sqlQueries.TableInfo, connection);
|
|
|
|
using (var reader = command.ExecuteReader(CommandBehavior.SingleRow))
|
|
{
|
|
if (reader.Read())
|
|
{
|
|
reporter.Warn(
|
|
$"Table with schema '{_schemaName}' and name '{_tableName}' already exists. " +
|
|
"Provide a different table name and try again.");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
using (var transaction = connection.BeginTransaction())
|
|
{
|
|
try
|
|
{
|
|
command = new SqlCommand(sqlQueries.CreateTable, connection, transaction);
|
|
|
|
reporter.Verbose($"Executing {command.CommandText}");
|
|
command.ExecuteNonQuery();
|
|
|
|
command = new SqlCommand(
|
|
sqlQueries.CreateNonClusteredIndexOnExpirationTime,
|
|
connection,
|
|
transaction);
|
|
|
|
reporter.Verbose($"Executing {command.CommandText}");
|
|
command.ExecuteNonQuery();
|
|
|
|
transaction.Commit();
|
|
|
|
reporter.Output("Table and index were created successfully.");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
reporter.Error(
|
|
$"An error occurred while trying to create the table and index. {ex.Message}");
|
|
transaction.Rollback();
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private void ValidateConnectionString()
|
|
{
|
|
try
|
|
{
|
|
new SqlConnectionStringBuilder(_connectionString);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new ArgumentException(
|
|
$"Invalid SQL Server connection string '{_connectionString}'. {ex.Message}", ex);
|
|
}
|
|
}
|
|
}
|
|
}
|