Skip to content
This repository has been archived by the owner on Jul 25, 2024. It is now read-only.

Commit

Permalink
Copy from main project
Browse files Browse the repository at this point in the history
  • Loading branch information
droyad committed Jan 24, 2024
1 parent 0a5465f commit 62b9f1f
Show file tree
Hide file tree
Showing 15 changed files with 410 additions and 7 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: CI

on:
#push:
#pull_request:
push:
pull_request:
workflow_dispatch:

jobs:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
DB Operation: Open connection
Info: Beginning database upgrade
Info: Checking whether journal table exists..
DB Operation: Execute scalar command: select cast(1 as Int) from systab t where t.table_name = 'SCHEMAVERSIONS'
DB Operation: Dispose command
Info: Journal table does not exist
Info: Executing Database Server script 'Script0001.sql'
Info: Checking whether journal table exists..
DB Operation: Execute scalar command: select cast(1 as Int) from systab t where t.table_name = 'SCHEMAVERSIONS'
DB Operation: Dispose command
Info: Creating the [schemaversions] table
DB Operation: Execute non query command: create table [schemaversions] (
[Id] int identity not null constraint [PK_schemaversions_Id] primary key,
[ScriptName] nvarchar(255) not null,
[Applied] datetime not null
)
DB Operation: Dispose command
Info: The [schemaversions] table has been created
DB Operation: Execute non query command: script1contents
DB Operation: Dispose command
DB Operation: Create parameter
Info: DB Operation: Add parameter to command: scriptName=Script0001.sql
DB Operation: Create parameter
Info: DB Operation: Add parameter to command: applied=<date>
DB Operation: Execute non query command: insert into [schemaversions] (ScriptName, Applied) values (? ,?)
DB Operation: Dispose command
Info: Upgrade successful
DB Operation: Dispose connection
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
DB Operation: Open connection
Info: Beginning database upgrade
Info: Checking whether journal table exists..
DB Operation: Execute scalar command: select cast(1 as Int) from systab t where t.table_name = 'TESTSCHEMAVERSIONS'
DB Operation: Dispose command
Info: Journal table does not exist
Info: Executing Database Server script 'Script0001.sql'
Info: Checking whether journal table exists..
DB Operation: Execute scalar command: select cast(1 as Int) from systab t where t.table_name = 'TESTSCHEMAVERSIONS'
DB Operation: Dispose command
Info: Creating the [test].[TestSchemaVersions] table
DB Operation: Execute non query command: create table [test].[TestSchemaVersions] (
[Id] int identity not null constraint [PK_TestSchemaVersions_Id] primary key,
[ScriptName] nvarchar(255) not null,
[Applied] datetime not null
)
DB Operation: Dispose command
Info: The [test].[TestSchemaVersions] table has been created
DB Operation: Execute non query command: script1contents
DB Operation: Dispose command
DB Operation: Create parameter
Info: DB Operation: Add parameter to command: scriptName=Script0001.sql
DB Operation: Create parameter
Info: DB Operation: Add parameter to command: applied=<date>
DB Operation: Execute non query command: insert into [test].[TestSchemaVersions] (ScriptName, Applied) values (? ,?)
DB Operation: Dispose command
Info: Upgrade successful
DB Operation: Dispose connection
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
DB Operation: Open connection
Info: Beginning database upgrade
Info: Checking whether journal table exists..
DB Operation: Execute scalar command: select cast(1 as Int) from systab t where t.table_name = 'SCHEMAVERSIONS'
DB Operation: Dispose command
Info: Journal table does not exist
Info: Executing Database Server script 'Script0001.sql'
Info: Checking whether journal table exists..
DB Operation: Execute scalar command: select cast(1 as Int) from systab t where t.table_name = 'SCHEMAVERSIONS'
DB Operation: Dispose command
Info: Creating the [schemaversions] table
DB Operation: Execute non query command: create table [schemaversions] (
[Id] int identity not null constraint [PK_schemaversions_Id] primary key,
[ScriptName] nvarchar(255) not null,
[Applied] datetime not null
)
DB Operation: Dispose command
Info: The [schemaversions] table has been created
DB Operation: Execute non query command: print SubstitutedValue
DB Operation: Dispose command
DB Operation: Create parameter
Info: DB Operation: Add parameter to command: scriptName=Script0001.sql
DB Operation: Create parameter
Info: DB Operation: Add parameter to command: applied=<date>
DB Operation: Execute non query command: insert into [schemaversions] (ScriptName, Applied) values (? ,?)
DB Operation: Dispose command
Info: Upgrade successful
DB Operation: Dispose connection
38 changes: 38 additions & 0 deletions src/Tests/ApprovalFiles/NoPublicApiChanges.Run.Net.verified.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

public static class SqlAnywhereExtensions
{
public static DbUp.Builder.UpgradeEngineBuilder SqlAnywhereDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString) { }
}
namespace DbUp.SqlAnywhere
{
public class SqlAnywhereConnectionManager : DbUp.Engine.Transactions.DatabaseConnectionManager, DbUp.Engine.Transactions.IConnectionManager
{
public SqlAnywhereConnectionManager(string connectionString) { }
public override System.Collections.Generic.IEnumerable<string> SplitScriptIntoCommands(string scriptContents) { }
}
public class SqlAnywhereObjectParser : DbUp.Support.SqlObjectParser, DbUp.Engine.ISqlObjectParser
{
public SqlAnywhereObjectParser() { }
public override string QuoteIdentifier(string objectName, DbUp.Support.ObjectNameOptions objectNameOptions) { }
}
public class SqlAnywhereScriptExecutor : DbUp.Support.ScriptExecutor, DbUp.Engine.IScriptExecutor
{
public SqlAnywhereScriptExecutor(System.Func<DbUp.Engine.Transactions.IConnectionManager> connectionManagerFactory, System.Func<DbUp.Engine.Output.IUpgradeLog> log, string schema, System.Func<bool> variablesEnabled, System.Collections.Generic.IEnumerable<DbUp.Engine.IScriptPreprocessor> scriptPreprocessors, System.Func<DbUp.Engine.IJournal> journalFactory) { }
protected override void ExecuteCommandsWithinExceptionHandler(int index, DbUp.Engine.SqlScript script, System.Action excuteCommand) { }
protected override string GetVerifySchemaSql(string schema) { }
}
public class SqlAnywhereSqlPreprocessor : DbUp.Engine.IScriptPreprocessor
{
public SqlAnywhereSqlPreprocessor() { }
public string Process(string contents) { }
}
public class SqlAnywhereTableJournal : DbUp.Support.TableJournal, DbUp.Engine.IJournal
{
public static System.Globalization.CultureInfo English;
public SqlAnywhereTableJournal(System.Func<DbUp.Engine.Transactions.IConnectionManager> connectionManager, System.Func<DbUp.Engine.Output.IUpgradeLog> logger, string schema, string table) { }
protected override string CreateSchemaTableSql(string quotedPrimaryKeyName) { }
protected override string DoesTableExistSql() { }
protected override string GetInsertJournalEntrySql(string scriptName, string applied) { }
protected override string GetJournalEntriesSql() { }
}
}
20 changes: 20 additions & 0 deletions src/Tests/DatabaseSupportTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using DbUp.Builder;
using DbUp.Tests.Common;

namespace DbUp.SqlAnywhere.Tests;

public class DatabaseSupportTests : DatabaseSupportTestsBase
{
public DatabaseSupportTests() : base()
{
}

protected override UpgradeEngineBuilder DeployTo(SupportedDatabases to)
=> to.SqlAnywhereDatabase("");

protected override UpgradeEngineBuilder AddCustomNamedJournalToBuilder(UpgradeEngineBuilder builder, string schema, string tableName)
=> builder.JournalTo(
(connectionManagerFactory, logFactory)
=> new SqlAnywhereTableJournal(connectionManagerFactory, logFactory, schema, tableName)
);
}
11 changes: 11 additions & 0 deletions src/Tests/NoPublicApiChanges.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using DbUp.Tests.Common;

namespace DbUp.SqlAnywhere.Tests;

public class NoPublicApiChanges : NoPublicApiChangesBase
{
public NoPublicApiChanges()
: base(typeof(SqlAnywhereExtensions).Assembly)
{
}
}
2 changes: 1 addition & 1 deletion src/Tests/Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net462</TargetFrameworks>
<TargetFramework>net462</TargetFramework>
<AssemblyName>Tests</AssemblyName>
<RootNamespace>DbUp.SqlAnywhere.Tests</RootNamespace>
<!-- <ImplicitUsings>enable</ImplicitUsings> Can't use implict usings with net46 -->
Expand Down
29 changes: 29 additions & 0 deletions src/dbup-sqlanywhere/SqlAnywhereConnectionManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using DbUp.Engine.Transactions;
using Sap.Data.SQLAnywhere;

namespace DbUp.SqlAnywhere
{
public class SqlAnywhereConnectionManager : DatabaseConnectionManager
{
/// <summary>
/// Split text on ; or GO and ignore those between Being and End statements
/// </summary>
static readonly Regex splitOnCommaOrGoRegEx = new Regex(@"\s*(?:(?<!BEGIN(?:.(?!END))*)(?:;|\n\s*GO\s*\n)(?!(?:.(?<!BEGIN))*END))\s*",
RegexOptions.IgnoreCase | RegexOptions.Singleline);

public SqlAnywhereConnectionManager(string connectionString) : base(l => new SAConnection(connectionString))
{
}

public override IEnumerable<string> SplitScriptIntoCommands(string scriptContents)
{
var stringSeparators = new string[] { "GO" };
var parts = scriptContents.Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries).ToList();
return parts.Select(x => x.Trim()).Where(x => x.Length > 0).ToArray();
}
}
}
50 changes: 50 additions & 0 deletions src/dbup-sqlanywhere/SqlAnywhereExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using DbUp.Builder;
using DbUp.Engine.Transactions;
using DbUp.SqlAnywhere;

/// <summary>
/// Configuration extension methods for SQL Anywhere.
/// </summary>
// ReSharper disable once CheckNamespace
public static class SqlAnywhereExtensions
{
/// <summary>
/// Creates an upgrader for Sql Anywhere databases.
/// </summary>
/// <param name="supported">Fluent helper type.</param>
/// <param name="connectionString">Sql Anywhere database connection string.</param>
/// <returns>
/// A builder for a database upgrader designed for Sql Anywhere databases.
/// </returns>
public static UpgradeEngineBuilder SqlAnywhereDatabase(this SupportedDatabases supported, string connectionString)
{
var builder = new UpgradeEngineBuilder();
builder.Configure(c => c.ConnectionManager = new SqlAnywhereConnectionManager(connectionString));
builder.Configure(c => c.ScriptExecutor = new SqlAnywhereScriptExecutor(() => c.ConnectionManager, () => c.Log, null, () => c.VariablesEnabled, c.ScriptPreprocessors, () => c.Journal));
builder.Configure(c => c.Journal = new SqlAnywhereTableJournal(() => c.ConnectionManager, () => c.Log, null, "schemaversions"));
return builder;
}

/// <summary>
/// Creates an upgrader for SQL Server databases.
/// </summary>
/// <param name="connectionManager">The <see cref="IConnectionManager"/> to be used during a database
/// upgrade. See <see cref="SqlAnywhereConnectionManager"/> for an example implementation</param>
/// <param name="schema">The SqlAnywhere schema name to use. Defaults to ''.</param>
/// <returns>
/// A builder for a database upgrader designed for SqlAnywhere databases.
/// </returns>
static UpgradeEngineBuilder SqlAnywhereDatabase(IConnectionManager connectionManager, string schema)
{
var builder = new UpgradeEngineBuilder();
builder.Configure(c => c.ConnectionManager = connectionManager);
builder.Configure(c => c.ScriptExecutor = new SqlAnywhereScriptExecutor(() => c.ConnectionManager, () => c.Log, schema, () => c.VariablesEnabled, c.ScriptPreprocessors, () => c.Journal));
builder.Configure(c => c.Journal = new SqlAnywhereTableJournal(() => c.ConnectionManager, () => c.Log, schema, "SchemaVersions"));
return builder;
}





}
47 changes: 47 additions & 0 deletions src/dbup-sqlanywhere/SqlAnywhereObjectParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Linq;
using DbUp.Support;

namespace DbUp.SqlAnywhere
{
/// <summary>
/// Parses Sql Objects and performs quoting functions
/// </summary>
public class SqlAnywhereObjectParser : SqlObjectParser
{
public SqlAnywhereObjectParser() : base("[", "]")
{
}

/// <summary>
/// Quotes the SqlAnywhere identifier to allow Special characters in the object name.
/// This function implements System.Data.SqlClient.SqlCommandBuilder.QuoteIdentifier() with an additional
/// validation which is missing from the SqlCommandBuilder version.
/// </summary>
/// <param name="objectName">Name of the object to quote.</param>
/// <param name="objectNameOptions">The settings which indicate if the whitespace should be dropped or not.</param>
/// <returns>The quoted object name</returns>
public override string QuoteIdentifier(string objectName, ObjectNameOptions objectNameOptions)
{
if (string.IsNullOrEmpty(objectName))
throw new ArgumentNullException();


if (ObjectNameOptions.Trim == objectNameOptions)
objectName = objectName.Trim();


const int SqlSysnameLength = 128;
if (objectName.Length > SqlSysnameLength)
throw new ArgumentOutOfRangeException(@"objectName", "A SqlAnywhere object name is maximum 128 characters long");


// The ] in the string need to be doubled up so it means we always need an un-even number of ]
if (objectName.StartsWith("[") && objectName.EndsWith("]") && objectName.Count(x => x == ']') % 2 == 1)
return objectName;


return string.Concat("[", objectName.Replace("]", "]]"), "]");
}
}
}
51 changes: 51 additions & 0 deletions src/dbup-sqlanywhere/SqlAnywhereScriptExecutor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using DbUp.Engine;
using DbUp.Engine.Output;
using DbUp.Engine.Transactions;
using DbUp.Support;

namespace DbUp.SqlAnywhere
{
/// <summary>
/// A standard implementation of the ScriptExecutor that executes against a SqlAnywhere
/// database.
/// </summary>
public class SqlAnywhereScriptExecutor : ScriptExecutor
{
/// <summary>
/// Initializes an instance of the <see cref="SqlAnywhereScriptExecutor"/> class.
/// </summary>
/// <param name="connectionManagerFactory"></param>
/// <param name="log">The logging mechanism.</param>
/// <param name="schema">The schema that contains the table.</param>
/// <param name="variablesEnabled">Function that returns <c>true</c> if variables should be replaced, <c>false</c> otherwise.</param>
/// <param name="scriptPreprocessors">Script Preprocessors in addition to variable substitution</param>
/// <param name="journalFactory">Database journal</param>
public SqlAnywhereScriptExecutor(Func<IConnectionManager> connectionManagerFactory, Func<IUpgradeLog> log, string schema, Func<bool> variablesEnabled,
IEnumerable<IScriptPreprocessor> scriptPreprocessors, Func<IJournal> journalFactory)
: base(connectionManagerFactory, new SqlAnywhereObjectParser(), log, schema, variablesEnabled, scriptPreprocessors, journalFactory)
{
}

protected override string GetVerifySchemaSql(string schema)
{
throw new NotSupportedException();
}

protected override void ExecuteCommandsWithinExceptionHandler(int index, SqlScript script, Action excuteCommand)
{
try
{
excuteCommand();
}
catch (Sap.Data.SQLAnywhere.SAException sqlException)
{
Log().WriteInformation("SQLAnywhere exception has occured in script: '{0}'", script.Name);
Log().WriteError("Script block number: {0}; Message: {1}", index, sqlException.Message);
Log().WriteError(sqlException.ToString());
throw;
}
}
}
}
15 changes: 15 additions & 0 deletions src/dbup-sqlanywhere/SqlAnywhereSqlPreprocessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using DbUp.Engine;

namespace DbUp.SqlAnywhere
{
/// <summary>
/// This preprocessor makes adjustments to your sql to make it compatible with Sql Anywhere.
/// </summary>
public class SqlAnywhereSqlPreprocessor : IScriptPreprocessor
{
public string Process(string contents)
{
return contents;
}
}
}
Loading

0 comments on commit 62b9f1f

Please sign in to comment.