Something went wrong. Try again.
A database migration tool for .NET
Something went wrong. Try again.
3.1 kB · 98 lines
C#
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899using System;using System.IO;using System.Text.RegularExpressions;
namespace Migrato.Core;
/// <summary>/// Parses a "-- +migrato Up" / "-- +migrato Down" annotated SQL file into a <see cref="Migration"/>/// </summary>public static partial class MigrationParser{ private const string UpMarker = "-- +migrato Up"; private const string DownMarker = "-- +migrato Down";
/// <summary> /// Parses the migration file at <paramref name="path"/> /// </summary> /// <exception cref="MigrationFormatException">The file name or contents do not follow Migrato's conventions</exception> public static Migration Parse(string path) { var fileName = Path.GetFileName(path); var match = FileNameRegex().Match(fileName); if (!match.Success) { throw new MigrationFormatException( $"'{fileName}' is not a valid migration file name; expected '<14-digit version>_<name>.sql'"); }
var version = long.Parse(match.Groups["version"].Value); var name = match.Groups["name"].Value;
var content = File.ReadAllText(path); var (upSql, downSql) = ParseSections(content, fileName);
return new Migration(version) { Source = path, Name = name, UpSql = upSql, DownSql = downSql, }; }
private static (string UpSql, string DownSql) ParseSections(string content, string fileName) { var lines = content.Replace("\r\n", "\n").Split('\n');
var upIndex = -1; var downIndex = -1;
for (var i = 0; i < lines.Length; i++) { var trimmed = lines[i].Trim();
if (trimmed.Equals(UpMarker, StringComparison.OrdinalIgnoreCase)) { if (upIndex != -1) { throw new MigrationFormatException($"'{fileName}' has more than one '{UpMarker}' marker"); }
upIndex = i; } else if (trimmed.Equals(DownMarker, StringComparison.OrdinalIgnoreCase)) { if (downIndex != -1) { throw new MigrationFormatException($"'{fileName}' has more than one '{DownMarker}' marker"); }
downIndex = i; } }
if (upIndex == -1) { throw new MigrationFormatException($"'{fileName}' is missing a '{UpMarker}' marker"); }
if (downIndex == -1) { throw new MigrationFormatException($"'{fileName}' is missing a '{DownMarker}' marker"); }
if (downIndex < upIndex) { throw new MigrationFormatException($"'{fileName}' has '{DownMarker}' before '{UpMarker}'"); }
var upSql = string.Join('\n', lines[(upIndex + 1)..downIndex]).Trim(); var downSql = string.Join('\n', lines[(downIndex + 1)..]).Trim();
return (upSql, downSql); }
[GeneratedRegex(@"^(?<version>\d{14})_(?<name>.+)\.sql$")] private static partial Regex FileNameRegex();}