Skip to content

Commit

Permalink
Fix unquoting bug. (#36)
Browse files Browse the repository at this point in the history
* Fix unquoting bug.

* Correct changelog.

* Fix test sproc names,
  • Loading branch information
chullybun committed Mar 28, 2023
1 parent 32002ac commit 91cab4f
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 22 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Represents the **NuGet** versions.

## v2.3.3
- *Fixed:* The unquoting of identifiers whilst parsing schema objects resulted in an empty identifier where the quote was not specified; i.e. for SQL Server `[dbo].[name]` worked, whereas, `dbo.name` did not; this has been corrected.

## v2.3.2
- *Fixed:* The `DotNetType` and `SqlType` property value determination has been improved; removed explicit `Prepare` to simplify.
- *Fixed:* Added `MigrationArgsBase.AcceptPrompts` to programmatically set the equivalent of the `--accept-prompts` command-line option.
Expand Down
2 changes: 1 addition & 1 deletion Common.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>2.3.2</Version>
<Version>2.3.3</Version>
<LangVersion>preview</LangVersion>
<Authors>Avanade</Authors>
<Company>Avanade</Company>
Expand Down
8 changes: 2 additions & 6 deletions src/DbEx.MySql/Migration/MySqlSchemaScript.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/DbEx

using DbEx.Migration;
using DbUp.MySql;
using DbUp.Support;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -37,10 +36,7 @@ public static MySqlSchemaScript Create(DatabaseMigrationScript migrationScript)
{
script.Type = tokens[i + 1];
script.FullyQualifiedName = tokens[i + 2];

var parser = new MySqlObjectParser();
script.Name = parser.UnquoteIdentifier(script.FullyQualifiedName);

script.Name = script.FullyQualifiedName;
return script;
}
}
Expand All @@ -53,7 +49,7 @@ public static MySqlSchemaScript Create(DatabaseMigrationScript migrationScript)
/// Initializes a new instance of the <see cref="MySqlSchemaScript"/> class.
/// </summary>
/// <param name="migrationScript">The parent <see cref="DatabaseMigrationScript"/>.</param>
private MySqlSchemaScript(DatabaseMigrationScript migrationScript) : base(migrationScript) { }
private MySqlSchemaScript(DatabaseMigrationScript migrationScript) : base(migrationScript, "`", "`") { }

/// <inheritdoc/>
public override string SqlDropStatement => $"DROP {Type.ToUpperInvariant()} IF EXISTS `{Name}`";
Expand Down
10 changes: 4 additions & 6 deletions src/DbEx.SqlServer/Migration/SqlServerSchemaScript.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/DbEx

using DbEx.Migration;
using DbUp.SqlServer;
using DbUp.Support;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -38,17 +37,16 @@ public static SqlServerSchemaScript Create(DatabaseMigrationScript migrationScri
script.Type = tokens[i + 1];
script.FullyQualifiedName = tokens[i + 2];

var parser = new SqlServerObjectParser();
var index = script.FullyQualifiedName.IndexOf('.');
if (index < 0)
{
script.Schema = "dbo";
script.Name = parser.UnquoteIdentifier(script.FullyQualifiedName);
script.Name = script.FullyQualifiedName;
}
else
{
script.Schema = parser.UnquoteIdentifier(script.FullyQualifiedName[..index]);
script.Name = parser.UnquoteIdentifier(script.FullyQualifiedName[(index + 1)..]);
script.Schema = script.FullyQualifiedName[..index];
script.Name = script.FullyQualifiedName[(index + 1)..];
}

return script;
Expand All @@ -63,7 +61,7 @@ public static SqlServerSchemaScript Create(DatabaseMigrationScript migrationScri
/// Initializes a new instance of the <see cref="SqlServerSchemaScript"/> class.
/// </summary>
/// <param name="migrationScript">The parent <see cref="DatabaseMigrationScript"/>.</param>
private SqlServerSchemaScript(DatabaseMigrationScript migrationScript) : base(migrationScript) { }
private SqlServerSchemaScript(DatabaseMigrationScript migrationScript) : base(migrationScript, "[", "]") { }

/// <inheritdoc/>
public override string SqlDropStatement => $"DROP {Type.ToUpperInvariant()} IF EXISTS [{Schema}].[{Name}]";
Expand Down
35 changes: 32 additions & 3 deletions src/DbEx/Migration/DatabaseSchemaScriptBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,37 @@ namespace DbEx.Migration
/// </summary>
public abstract class DatabaseSchemaScriptBase
{
private string? _schema;
private string _name = string.Empty;

/// <summary>
/// Initializes a new instance of the <see cref="DatabaseSchemaScriptBase"/> class.
/// </summary>
/// <param name="migrationScript">The <see cref="DatabaseMigrationScript"/>.</param>
public DatabaseSchemaScriptBase(DatabaseMigrationScript migrationScript) => MigrationScript = migrationScript ?? throw new ArgumentNullException(nameof(migrationScript));
/// <param name="quotePrefix">The optional quote prefix.</param>
/// <param name="quoteSuffix">The optional quote suffix.</param>
public DatabaseSchemaScriptBase(DatabaseMigrationScript migrationScript, string? quotePrefix = null, string? quoteSuffix = null)
{
MigrationScript = migrationScript ?? throw new ArgumentNullException(nameof(migrationScript));
QuotePrefix = quotePrefix;
QuoteSuffix = quoteSuffix;
}

/// <summary>
/// Gets the parent <see cref="DatabaseMigrationScript"/>.
/// </summary>
public DatabaseMigrationScript MigrationScript { get; }

/// <summary>
/// Gets the optional quote prefix.
/// </summary>
public string? QuotePrefix { get; }

/// <summary>
/// Gets the optional quote suffix.
/// </summary>
public string? QuoteSuffix { get; }

/// <summary>
/// Gets or sets the fully qualified name (as per script).
/// </summary>
Expand All @@ -34,13 +54,13 @@ public abstract class DatabaseSchemaScriptBase
/// Gets or sets the underlying schema name (where applicable).
/// </summary>
/// <remarks>This is schema portion of the <see cref="FullyQualifiedName"/> with any escaping removed.</remarks>
public string? Schema { get; protected set; }
public string? Schema { get => _schema; protected set => _schema = UnquoteIdentifier(value); }

/// <summary>
/// Gets the object name.
/// </summary>
/// <remarks>This is name portion of the <see cref="FullyQualifiedName"/> with any escaping removed.</remarks>
public string Name { get; protected set; } = string.Empty;
public string Name { get => _name; protected set => _name = UnquoteIdentifier(value)!; }

/// <summary>
/// Gets the <see cref="Type"/> order of precedence.
Expand Down Expand Up @@ -72,5 +92,14 @@ public abstract class DatabaseSchemaScriptBase
/// </summary>
/// <remarks>This is only used for logging; the original script is invoked.</remarks>
public abstract string SqlCreateStatement { get; }

/// <summary>
/// Unquotes the <paramref name="identifier"/> by removing the <see cref="QuotePrefix"/> and <see cref="QuoteSuffix"/> where they both exist.
/// </summary>
/// <param name="identifier">The identifier to unquote.</param>
/// <returns>The unquoted identifier.</returns>
public string? UnquoteIdentifier(string? identifier)
=> !string.IsNullOrEmpty(identifier) && !string.IsNullOrEmpty(QuotePrefix) && !string.IsNullOrEmpty(QuoteSuffix) && identifier.StartsWith(QuotePrefix, StringComparison.OrdinalIgnoreCase) && identifier.EndsWith(QuoteSuffix, StringComparison.OrdinalIgnoreCase)
? identifier[QuotePrefix.Length..^QuoteSuffix.Length] : identifier;
}
}
5 changes: 0 additions & 5 deletions tests/DbEx.Test.Console/DbEx.Test.Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
<EmbeddedResource Include="Data\**\*" />
</ItemGroup>

<ItemGroup>
<None Remove="Data\Other.sql" />
<None Remove="Migrations\000.post.database.create.sql" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\DbEx.SqlServer\DbEx.SqlServer.csproj" />
<ProjectReference Include="..\..\src\DbEx\DbEx.csproj" />
Expand Down
2 changes: 1 addition & 1 deletion tests/DbEx.Test.Console/Schema/spGetContact.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CREATE PROCEDURE [Test].[spGetContact]
CREATE PROCEDURE Test.spGetContact
@ContactId AS INT /* this is a comment */
AS
BEGIN
Expand Down
8 changes: 8 additions & 0 deletions tests/DbEx.Test.Console/Schema/spGetContact2.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE PROCEDURE [Test].[spGetContact2]
@ContactId AS INT /* this is a comment */
AS
BEGIN
-- This is a comment.
SET NOCOUNT ON;
SELECT * FROM [Test].[Contact] AS [c] WHERE [c].[ContactId] = @ContactId
END

0 comments on commit 91cab4f

Please sign in to comment.