Skip to content

Instantly share code, notes, and snippets.

@Hallmanac
Last active April 21, 2017 10:36
Show Gist options
  • Save Hallmanac/74c8c1ec179c68fba0ebcda7fff304af to your computer and use it in GitHub Desktop.
Save Hallmanac/74c8c1ec179c68fba0ebcda7fff304af to your computer and use it in GitHub Desktop.
Concat SQL script files into one bundled SQL script file. Then parse out the bundled file by splitting on the "Go" statements and execute each script line one at a time.
using System.IO;
using System.Text;
using Funqy.CSharp;
namespace Hallmanac.SqlScriptConcat
{
public class BundleSqlScripts
{
public FunqResult ExecuteBundling()
{
var parentDirectory = Directory.GetParent(Directory.GetCurrentDirectory());
if (parentDirectory == null)
return FunqFactory.ResultFail("No parent directory was found");
var parentOfParentDirectory = parentDirectory.Parent;
if (parentOfParentDirectory == null)
return FunqFactory.ResultFail("No super parent directory was found");
var currentProjectDirectory = parentOfParentDirectory.FullName;
var sqlScriptsPath = Path.GetFullPath(Path.Combine(currentProjectDirectory, "..\\Project.Repo\\SqlScripts"));
var allFiles = Directory.GetFiles(sqlScriptsPath, "*.sql", SearchOption.AllDirectories);
using (var outputStream = File.Create(Path.Combine(sqlScriptsPath, "..\\SqlScripts_bundle.sql")))
{
var sb = new StringBuilder();
foreach (var sqlFile in allFiles)
{
sb.AppendLine(File.ReadAllText(sqlFile, Encoding.UTF8));
sb.AppendLine("\n");
}
var outputBytes = Encoding.UTF8.GetBytes(sb.ToString());
outputStream.Write(outputBytes, 0, outputBytes.Length);
}
return FunqFactory.ResultOk();
}
}
}
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Funqy.CSharp;
namespace Hallmanac.SqlScriptConcat
{
public class SqlScriptFileExecution
{
public FunqResult ExecuteSqlScriptFile(string filePathAndName, string connectionString)
{
if (string.IsNullOrEmpty(filePathAndName))
return FunqFactory.ResultFail($"{nameof(filePathAndName)} was null");
if (string.IsNullOrEmpty(connectionString))
return FunqFactory.ResultFail($"{nameof(connectionString)} was null");
var fileContentsResult = GetFileContents(filePathAndName);
if (fileContentsResult.IsFailure)
return FunqFactory.ResultFail($"Could not get the file contents for the following reason: {fileContentsResult.Message}");
var bundleScripts = fileContentsResult.Value;
var bundleSqlCommands = SplitSqlStatements(bundleScripts);
using (var transaction = new TransactionScope())
{
using (var connection = new SqlConnection(connectionString))
{
// THIS ASSUMES THERE ARE NO "GO" STATEMENTS IN THE SCRIPT!!!
foreach (var command in bundleSqlCommands)
{
connection.Open();
using (var cmd = new SqlCommand(command, connection))
{
cmd.ExecuteNonQuery();
}
connection.Close();
}
}
transaction.Complete();
}
const string message = "Executed all Stored Procs and functions during startup.";
Debug.WriteLine(message);
Trace.WriteLine(message);
return FunqFactory.ResultOk(message);
}
public FunqResult ExecuteSqlResourceFile(string resourceName, Assembly assembly, string connectionString)
{
string bundleScripts;
using (var stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream != null)
{
using (var reader = new StreamReader(stream))
{
bundleScripts = reader.ReadToEnd();
}
}
else
{
bundleScripts = null;
}
}
var bundleSqlCommands = SplitSqlStatements(bundleScripts);
using (var transaction = new TransactionScope())
{
using (var connection = new SqlConnection(connectionString))
{
// THIS ASSUMES THERE ARE NO "GO" STATEMENTS IN THE SCRIPT!!!
foreach (var command in bundleSqlCommands)
{
connection.Open();
using (var cmd = new SqlCommand(command, connection))
{
cmd.ExecuteNonQuery();
}
connection.Close();
}
}
transaction.Complete();
}
const string message = "Executed all Stored Procs and functions during startup.";
Debug.WriteLine(message);
Trace.WriteLine(message);
return FunqFactory.ResultOk(message);
}
public string[] SplitSqlStatements(string sqlScript)
{
// Split by "GO" statements
var regex = new Regex(@"\r{0,1}\nGO\r{0,1}\n");
var commands = regex.Split(sqlScript);
//var stringSplitStatements = sqlScript.Split(new[] {"GO"}, StringSplitOptions.None);
// Remove empties, trim, and return
return commands
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => x.Trim(' ', '\r', '\n'))
.ToArray();
}
public FunqResult<string> GetFileContents(string watchedFileNameAndPath)
{
if (string.IsNullOrWhiteSpace(watchedFileNameAndPath))
return FunqFactory.ResultFail("The given path to the bank file was invalid.", (string)null);
try
{
var fileContents = File.ReadAllText(watchedFileNameAndPath);
return string.IsNullOrWhiteSpace(fileContents)
? FunqFactory.ResultFail("There is nothing in the given bank file.", (string)null)
: FunqFactory.ResultOk<string>(fileContents);
}
catch (Exception e)
{
var msg = $"An exception was thrown while getting the file contents. It is as follows: {e.Message}";
return FunqFactory.ResultFail(msg, (string)null);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment