- Notifications
You must be signed in to change notification settings - Fork691
ImproveMigrationAttribute#1966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Add VersionAsString to `MigrationAttribute` so customMigrationAttributes can display a decoded version of their numbering ruleupdate `MigrationInfo` to also support new Property
jzabroski commentedFeb 24, 2025
Hello, In terms of a decoded version of the numbering rule,can you just use a view (example below)? What we do on our team is:
Therefore, a database view can be constructed as follows (dialect is T-SQL for Microsoft SQL Server, and so the SELECT Version, TRY_CONVERT(DATE, LEFT(Version,8),112/* yyyyMMdd*/)AS VersionDate, CAST(RIGHT(Version,2)ASINT)AS SequenceNumberFROMdbo.VersionInfo |
mafoo-ASC commentedFeb 24, 2025
As version only stores a long that makes only 8 bytes of available data. We wanted to pack a usingFluentMigrator;publicclassVersionMigrationAttribute:MigrationAttribute{/// <summary>/// Represents the version information related to this Migration/// </summary>/// <param name="major"></param>/// <param name="minor"></param>/// <param name="revision"></param>/// <param name="order">Order for match to apply (must be unique across previous information</param>/// <param name="description">/// <inheritdoc cref="MigrationAttribute.Description" />/// </param>publicVersionMigrationAttribute(ushortmajor,ushortminor,ushortrevision,ushortorder,string?description=null):base(VersionMigrationAttribute.FormatRevision(major,minor,revision,order),description){this.AsVersion=newVersion(major,minor,revision);this.Order=order;}[Obsolete("We only want to use a fixed format")]publicVersionMigrationAttribute(longversion,stringdescription):base(version,description){thrownewNotSupportedException("Only use the full format constructors");}[Obsolete("We only want to use a fixed format")]publicVersionMigrationAttribute(longversion,TransactionBehaviortransactionBehavior=TransactionBehavior.Default,string?description=null):base(version,transactionBehavior,description){thrownewNotSupportedException("Only use the full format constructors");}publicVersionMigrationAttribute(ushortmajor,ushortminor,ushortrevision,ushortorder,TransactionBehaviortransactionBehavior,string?description=null):base(VersionMigrationAttribute.FormatRevision(major,minor,revision,order),transactionBehavior,description){this.AsVersion=newVersion(major,minor,revision);this.Order=order;}publicVersionAsVersion{get;init;}publicushortOrder{get;init;}/// <summary>/// Convert supplied <paramref name="version" /> to human-readable version/// </summary>/// <param name="version"></param>/// <param name="asVersion"></param>/// <param name="order"></param>publicstaticvoidExtractData(longversion,outVersionasVersion,outushortorder){varbytes=(Span<byte>)BitConverter.GetBytes(version);asVersion=newVersion(BitConverter.ToUInt16(bytes[7..8]),BitConverter.ToUInt16(bytes[5..6]),BitConverter.ToUInt16(bytes[3..4]));order=BitConverter.ToUInt16(bytes[1..2]);}publicstringVersionToString()=>VersionMigrationAttribute.Format(this.AsVersion,this.Order);privatestaticstringFormat(Versionversion,ushortorder)=>$"Version:{version}, Order:{order}";/// <summary>/// Pack provided version information into required format/// </summary>/// >/// <param name="major"></param>/// <param name="minor"></param>/// <param name="revision"></param>/// <param name="order"></param>/// <exception cref="ArgumentOutOfRangeException"></exception>privatestaticlongFormatRevision(ushortmajor,ushortminor,ushortrevision,ushortorder){try{_=newVersion(major,minor,revision);}catch(Exceptionex){thrownewArgumentOutOfRangeException($"Could not parse version provided by{nameof(major)}/{nameof(minor)}/{nameof(revision)}",ex);}using(vars=newMemoryStream())using(varw=newBinaryWriter(s)){w.Write(order);w.Write(revision);w.Write(minor);w.Write(major);returnBitConverter.ToInt64(s.ToArray());}}} |
jzabroski commentedFeb 24, 2025
Thank you, the fact long only stores 8 bytes is a good argument to potentially extend to support a double long.
When you say Completely separately from whether I understood your ask: |
mafoo-ASC commentedFeb 25, 2025
Yes we are planning to use an assembly Version to represent the release that we are working on specifically we are targetingSystem.Version and including a order field on the end so the patches can both be unique (as that is required) and ordered. Regarding commit id, storing optional data would be really handy, can i suggest string?/nvarchar(max) as this would leave users free to store what they wish (including json) |
jzabroski commentedFeb 25, 2025
C# supportsUInt128, andUIntPtr (nuint). byte[] and Span are not hard requirements, although interesting approaches to consider. I would propose we make MigrationAttribute have a generic abstract base class where the generic argument is an IBinaryInteger. Per the documentation, this would allow you to have Once there is an ABC for MigrationAttribute, the existing MigrationAttribute everyone uses can just be implemented as a closed generic type in terms of This to me seems a lot cleaner and while it would be an ABI breaking change, and some uses of Reflection might break, the core API would not break any C# syntax or require odd customizations from end-users who don't want this complexity. Thoughts? |
mafoo-ASC commentedFeb 25, 2025
Fair point on the Yes moving to an abstract type would certainly help as it allows an individual to choose more storage if they want to without breaking exiting users.
As to the With supporting System.Version we we develop a lot of projects following the Sprint principle so we are aiming to get the work done within a specific sprint with each sprint being assigned a Version e.g. 1.2.x we can then recognise the source of the patch to the sprint it was related too. |
Add VersionAsString to
MigrationAttributeso customMigrationAttributes can display a decoded version of their numbering rule updateMigrationInfoto also support new Property