Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add scripting API implemented by the SqlScriptPublishModel #316

Merged
merged 34 commits into from Apr 24, 2017
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
30c07eb
Add nuget package SqlScriptPublishModel.
pensivebrian Mar 12, 2017
2e6813a
Initial commit of the scripting service.
pensivebrian Mar 21, 2017
9e2dfe3
Add list object and script object support to the scripter service.
pensivebrian Mar 22, 2017
5b2f86b
Merge dev branch
pensivebrian Mar 26, 2017
b6e5c59
Refresh SMO from SSMS_Rel 14.0.17049.0
pensivebrian Mar 31, 2017
9d9438a
Add scripting include/exclude object filter support
pensivebrian Apr 7, 2017
dba5ed5
Fix null ref in ScriptingObject.GetHashCode()
pensivebrian Apr 7, 2017
81ea9ea
Log object being scripted
pensivebrian Apr 8, 2017
43f4d4b
Fix scripting against SQL running in a docker container.
pensivebrian Apr 9, 2017
4fe577b
Refactor scripting operation to lazily load the server name from SMO
pensivebrian Apr 14, 2017
c1ce933
merging dev
pensivebrian Apr 14, 2017
47db0c9
Format ScriptingOptions.cs
pensivebrian Apr 14, 2017
1c38721
Reformat some of the scripting operations
pensivebrian Apr 14, 2017
5d42466
Merge dev
pensivebrian Apr 14, 2017
562c693
Bump SMO version in doc samples
pensivebrian Apr 14, 2017
6024b0e
Run srgen and fix build and test failures
pensivebrian Apr 14, 2017
4a2a965
Rename the ScriptingService method from HandleExecuteRequest to Handl…
pensivebrian Apr 14, 2017
d32d820
Reuse a shared northwind database to speed up the scripting tests
pensivebrian Apr 15, 2017
b801efb
Docs the ScriptingExtensionMethods class
pensivebrian Apr 15, 2017
9be1640
Add docs to ScriptingObjectMatchProcessor
pensivebrian Apr 15, 2017
ce48e89
Introduce a Cleanup method for the TestDriver.Tests
pensivebrian Apr 15, 2017
83afb81
Actually reuse the same Northwind database for all scripting tests
pensivebrian Apr 15, 2017
e492c32
SMO Urn and code review fixes
pensivebrian Apr 17, 2017
8771009
Misc code review fixes and docs
pensivebrian Apr 19, 2017
327c659
Merging dev
pensivebrian Apr 19, 2017
7f1b685
Code review feedback
pensivebrian Apr 20, 2017
4ad88e9
Misc Fixes
pensivebrian Apr 20, 2017
8df5a61
Use resources for string and rename ScriptingListObjectsCompleteParam…
pensivebrian Apr 20, 2017
a1e56de
Fix test ScriptSchemaInvalidConnectionString and shorten a few test t…
pensivebrian Apr 20, 2017
a596f54
User nullable bools for the ScriptOptions properties
pensivebrian Apr 20, 2017
56f6977
Merge branch 'dev' into feature/scripterService
pensivebrian Apr 21, 2017
d7bbd85
Doc update for ScriptingObjectMatchProcessor
pensivebrian Apr 21, 2017
60b4afd
Rename ScriptingObjectMatchProcessor to ScriptingObjectMatcher
pensivebrian Apr 24, 2017
aeffd07
Merge branch 'dev' into feature/scripterService
pensivebrian Apr 24, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file removed bin/nuget/Microsoft.SqlServer.Smo.14.0.17028.nupkg
Binary file not shown.
Binary file not shown.
6 changes: 3 additions & 3 deletions docs/samples/jsonrpc/netcore/executequery/project.json
Expand Up @@ -4,19 +4,19 @@
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true
},
},
"dependencies": {
"Microsoft.SqlTools.ServiceLayer": {
"target": "project"
},
"Newtonsoft.Json": "9.0.1",
"System.Data.Common": "4.1.0",
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
"Microsoft.SqlServer.Smo": "14.0.17028",
"Microsoft.SqlServer.Smo": "140.17049.0",
"System.Security.SecureString": "4.0.0",
"System.Collections.Specialized": "4.0.1",
"System.ComponentModel.TypeConverter": "4.1.0",
"System.Diagnostics.Contracts": "4.0.1",
"System.Diagnostics.Contracts": "4.0.1",
"System.Diagnostics.TraceSource": "4.0.0",
"NETStandard.Library": "1.6.0",
"Microsoft.NETCore.Runtime.CoreCLR": "1.0.2",
Expand Down
2 changes: 1 addition & 1 deletion docs/samples/smo/netcore/ModifySetting/project.json
Expand Up @@ -5,7 +5,7 @@
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.SqlServer.Smo": "14.0.17028"
"Microsoft.SqlServer.Smo": "140.17049.0"
},
"frameworks": {
"netcoreapp1.0": {
Expand Down
@@ -0,0 +1,22 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.SqlTools.Hosting.Protocol.Contracts;

namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts
{
/// <summary>
/// Parameters sent when a scripting operation has been canceled.
/// </summary>
public class ScriptingCancelParameters : ScriptingEventParams { }

/// <summary>
/// Event sent to indicate that a scripting operation has been canceled.
/// </summary>
public class ScriptingCancelEvent
Copy link
Contributor

@benrr101 benrr101 Apr 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In previous API requests (edit/initialize in particular) we have a single event that is raised when the initialization is completed (edit/initializeSessionReady). The event has parameters to indicate success or failure. This also makes it simpler on the client side to implement b/c there is only one listener for the edit/initializeSessionReady event. In this scenario, you'll need to create 3 listeners (complete, cancel, and error) that will need to be shut down when any one of them receives an event.
Since you've got a different payload to include with each kind of event, I can see why using separate events would be beneficial, but it is slightly different than the APIs already developed. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to combine completed and cancel if that's the pattern used by services.

{
public static readonly EventType<ScriptingCancelParameters> Type = EventType<ScriptingCancelParameters>.Create("scripting/scriptCancel");
}
}
@@ -0,0 +1,34 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.SqlTools.Hosting.Protocol.Contracts;

namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts
{
/// <summary>
/// Parameters to cancel a scripting request.
/// </summary>
public class ScriptingCancelParams
{
/// <summary>
/// Gets or sets the operation id of the scripting operation to cancel.
/// </summary>
public string OperationId { get; set; }
Copy link
Contributor

@benrr101 benrr101 Apr 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming this should inherit from ScriptingEventParams? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, nice catch.

}

/// <summary>
/// Parameters returned from a scripting request.
/// </summary>
public class ScriptingCancelResult { }

/// <summary>
/// Defines the scripting cancel request type.
/// </summary>
public class ScriptingCancelRequest
{
public static readonly RequestType<ScriptingCancelParams, ScriptingCancelResult> Type =
RequestType<ScriptingCancelParams, ScriptingCancelResult>.Create("scripting/scriptCancel");
}
}
@@ -0,0 +1,24 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.SqlTools.Hosting.Protocol.Contracts;

namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts
{
/// <summary>
/// Parameters sent to when a scripting operation has completed.
/// </summary>
public class ScriptingCompleteParameters : ScriptingEventParams {}


/// <summary>
/// Event sent to indicate a scripting operation has completed.
/// </summary>
public class ScriptingCompleteEvent
{
public static readonly EventType<ScriptingCompleteParameters> Type =
EventType<ScriptingCompleteParameters>.Create("scripting/scriptComplete");
}
}
@@ -0,0 +1,34 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.SqlTools.Hosting.Protocol.Contracts;

namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts
{
/// <summary>
/// Parameters sent when a scripting operation has encountered an error.
/// </summary>
public class ScriptingErrorParams : ScriptingEventParams
{
/// <summary>
/// Gets or sets error message.
/// </summary>
public string Message { get; set; }

/// <summary>
/// Gets or sets error details.
/// </summary>
public string Details { get; set; }
}

/// <summary>
/// Event sent to indicate a scripting operation has encountered an error.
/// </summary>
public class ScriptingErrorEvent
Copy link
Contributor

@kevcunnane kevcunnane Apr 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check with Ben, this is a nice practice / looks good but I know he's been doing work in the error handling area and it'd be great if we align this so it's consistent. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.


In reply to: 111651923 [](ancestors = 111651923)

{
public static readonly EventType<ScriptingErrorParams> Type =
EventType<ScriptingErrorParams>.Create("scripting/scriptError");
}
}
@@ -0,0 +1,18 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts
{
/// <summary>
/// Base class for all scripting event parameters.
/// </summary>
public abstract class ScriptingEventParams
Copy link
Contributor

@kevcunnane kevcunnane Apr 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please doc #Resolved

{
/// <summary>
/// Gets or sets the operation id of the scripting operation this event is associated with.
/// </summary>
public string OperationId { get; set; }
}
}
@@ -0,0 +1,34 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using System.Collections.Generic;
using Microsoft.SqlTools.Hosting.Protocol.Contracts;

namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts
{
/// <summary>
/// Parameters sent when a list objects operation has completed.
/// </summary>
public class ScriptingListObjectsCompleteParameters : ScriptingEventParams
{
/// <summary>
/// Gets or sets the list of database objects returned from the list objects operation.
/// </summary>
public List<ScriptingObject> DatabaseObjects { get; set; }
Copy link
Contributor

@kevcunnane kevcunnane Apr 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please doc #Resolved


/// <summary>
/// Gets or sets the count of database object returned from the list objects operation.
/// </summary>
public int Count { get; set; }
}

/// <summary>
/// Event sent to indicate a list objects operation has completed.
/// </summary>
public class ScriptingListObjectsCompleteEvent
{
public static readonly EventType<ScriptingListObjectsCompleteParameters> Type = EventType<ScriptingListObjectsCompleteParameters>.Create("scripting/listObjectsComplete");
}
}
@@ -0,0 +1,35 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using System.Collections.Generic;
using Microsoft.SqlTools.Hosting.Protocol.Contracts;

namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts
{
/// <summary>
/// Parameters for a list objects request.
/// </summary>
public class ScriptingListObjectsParams
{
public string ConnectionString { get; set; }
}

/// <summary>
/// Parameters returned from a list objects request.
/// </summary>
public class ScriptingListObjectsResult
{
public string OperationId { get; set; }
}

/// <summary>
/// Defines the scripting list objects request type.
/// </summary>
public class ScriptingListObjectsRequest
{
public static readonly RequestType<ScriptingListObjectsParams, ScriptingListObjectsResult> Type =
RequestType<ScriptingListObjectsParams, ScriptingListObjectsResult>.Create("scripting/listObjects");
}
}
@@ -0,0 +1,93 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using System;
using System.Collections.Generic;

namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts
{
/// <summary>
/// Class to represent a database object that can be scripted.
/// </summary>
public sealed class ScriptingObject : IEquatable<ScriptingObject>
{
/// <summary>
/// Gets or sets the database object type.
/// </summary>
/// <remarks>
/// This underlying values are determined by the SqlScriptPublishModel.GetDatabaseObjectTypes() and
/// can change depending on the version of SMO used by the tools service. Values can be:
/// Table,
/// View,
/// StoredProcedure,
/// UserDefinedFunction,
/// UserDefinedDataType,
/// User,
/// Default,
/// Rule,
/// DatabaseRole,
/// ApplicationRole,
/// SqlAssembly,
/// DdlTrigger,
/// Synonym,
/// XmlSchemaCollection,
/// Schema,
/// PlanGuide,
/// UserDefinedType,
/// UserDefinedAggregate,
/// FullTextCatalog,
/// UserDefinedTableType
Copy link
Contributor

@kevcunnane kevcunnane Apr 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will there be more in the future? We have a bunch of other types in the ObjectExplorer tree, can they all be added in here / should they be? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are dynamically discovered by SMO, so this list may change. I'll add comment about this.


In reply to: 111651987 [](ancestors = 111651987)

/// </remarks>
public string Type { get; set; }

/// <summary>
/// Gets or sets the schema of the database object.
/// </summary>
public string Schema { get; set; }

/// <summary>
/// Gets or sets the database object name.
/// </summary>
public string Name { get; set; }

public override string ToString()
{
string objectName = string.IsNullOrEmpty(this.Schema)
? this.Name
: this.Schema + "." + this.Name;

return objectName;
}

public override int GetHashCode()
Copy link
Contributor

@benrr101 benrr101 Apr 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm hoping this is the auto-implemented GetHashCode from ReSharper 😃 #WontFix

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I don't use ReSharper :)

{
return
StringComparer.OrdinalIgnoreCase.GetHashCode(this.Type ?? string.Empty) ^
StringComparer.OrdinalIgnoreCase.GetHashCode(this.Schema ?? string.Empty) ^
StringComparer.OrdinalIgnoreCase.GetHashCode(this.Name ?? string.Empty);
}

public override bool Equals(object obj)
{
return
obj != null &&
this.GetType() == obj.GetType() &&
this.Equals((ScriptingObject)obj);
}

public bool Equals(ScriptingObject other)
{
if (other == null)
{
return false;
}

return
string.Equals(this.Type, other.Type, StringComparison.OrdinalIgnoreCase) &&
string.Equals(this.Schema, other.Schema, StringComparison.OrdinalIgnoreCase) &&
string.Equals(this.Name, other.Name, StringComparison.OrdinalIgnoreCase);
}
}
}