Skip to content

Instantly share code, notes, and snippets.

@dazinator
Last active October 1, 2015 14:27
Show Gist options
  • Save dazinator/30b8b6c19302544b6981 to your computer and use it in GitHub Desktop.
Save dazinator/30b8b6c19302544b6981 to your computer and use it in GitHub Desktop.
T-SQL function that takes a Semantic Version number string (see semver.org) and returns its component parts - Major, Minor, Patch, PreReleaseLabel and BuildMetadata
create function dbo.ParseSemVerString
(
-- a semantic version number string that meets specification described here: http://semver.org/
@versionString NVARCHAR(300)
)
returns @T table(Major int, Minor int, Patch int, PreReleaseLabel nvarchar(200), BuildLabel nvarchar(200))
as
begin
declare @segmentDelimiter char(1)
set @segmentDelimiter = '.'
declare @major int
declare @minor int
declare @patch int
declare @preReleaseLabel nvarchar(200)
declare @buildLabel nvarchar(200)
select @major = s.Item
from dbo.SplitString(@versionstring, @segmentDelimiter) s
where s.ItemIndex = 0
select @minor = s.Item
from dbo.SplitString(@versionstring, @segmentDelimiter) s
where s.ItemIndex =1
declare @patchwithlabel nvarchar(406) -- a combination of length of patch digit (allowing 6 digits long) plus a pre-release label (200) plus build metadata label (200) == 406
select @patchwithlabel = COALESCE(@patchwithlabel + @segmentDelimiter, '') + s.Item
from dbo.SplitString(@versionstring, @segmentDelimiter) s
where s.ItemIndex > 1
--select @patchwithlabel PatchWithLabel
-- get the build label if any.
declare @buildMetadataDelimiter char(1)
set @buildMetadataDelimiter = '+'
select @buildLabel = s.Item
from dbo.SplitString(@patchwithlabel, @buildMetadataDelimiter) s
where s.ItemIndex =1
-- get the pre-release label if any
-- first get without the build label
declare @patchWithoutBuildLabel nvarchar(206)
select @patchWithoutBuildLabel = s.Item
from dbo.SplitString(@patchwithlabel, @buildMetadataDelimiter) s
where s.ItemIndex =0
-- now get only the pre-release label if any
declare @labelDelimiter char(1)
set @labelDelimiter = '-'
select @preReleaseLabel = COALESCE(@preReleaseLabel + @labelDelimiter, '') + s.Item
from dbo.SplitString(@patchWithoutBuildLabel, @labelDelimiter) s
where s.ItemIndex > 0
-- now get only the patch
select @patch = s.Item
from dbo.SplitString(@patchWithoutBuildLabel, @labelDelimiter) s
where s.ItemIndex =0
insert into @T(Major, Minor, Patch, PreReleaseLabel, BuildLabel) values (@major, @minor, @patch, @preReleaseLabel, @buildLabel)
return
end
create function dbo.SplitString
(
@str nvarchar(max),
@separator char(1)
)
returns table
AS
return (
with tokens(p, a, b) AS (
select
cast(1 as bigint),
cast(1 as bigint),
charindex(@separator, @str)
union all
select
p + 1,
b + 1,
charindex(@separator, @str, b + 1)
from tokens
where b > 0
)
select
p-1 ItemIndex,
substring(
@str,
a,
case when b > 0 then b-a ELSE LEN(@str) end)
AS Item
from tokens
);
DECLARE @semVersion nvarchar(100)
SET @semVersion = '1.0.0-alpha-1.1+build1234-a`
SELECT v.Major, v.Minor, v.Patch, v.PreReleaseLabel, v.BuildLabel
FROM dbo.ParseSemVerString(@semVersion) v
-- Returns
-- Major Minor Patch PreReleaseLabel BuildLabel
-- 1 0 0 alpha-1.1 build1234-a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment