mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 18:47:57 -05:00
Split sql batches into separate code cells for convert (#1100)
* Split sql batches into separate code cells for convert * remove unneeded sort
This commit is contained in:
@@ -16,9 +16,23 @@ using Newtonsoft.Json;
|
|||||||
using Microsoft.SqlServer.TransactSql.ScriptDom;
|
using Microsoft.SqlServer.TransactSql.ScriptDom;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.SqlTools.ServiceLayer.NotebookConvert;
|
using Microsoft.SqlTools.ServiceLayer.NotebookConvert;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.NotebookConvert
|
namespace Microsoft.SqlTools.ServiceLayer.NotebookConvert
|
||||||
{
|
{
|
||||||
|
enum NotebookTokenType
|
||||||
|
{
|
||||||
|
MultilineComment,
|
||||||
|
Batch
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotebookToken
|
||||||
|
{
|
||||||
|
public int StartOffset;
|
||||||
|
public string Text;
|
||||||
|
public NotebookTokenType TokenType;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main class for Notebook Convert Service
|
/// Main class for Notebook Convert Service
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -135,7 +149,7 @@ namespace Microsoft.SqlTools.ServiceLayer.NotebookConvert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Split the text into separate chunks - blocks of Mutliline comments and blocks
|
* Split the text into separate chunks - blocks of Mutliline comments and blocks
|
||||||
* of everything else. We then create a markdown cell for each multiline comment and a code
|
* of everything else (batches). We then create a markdown cell for each multiline comment and a code
|
||||||
* cell for the other blocks.
|
* cell for the other blocks.
|
||||||
* We only take multiline comments which aren't part of a batch - since otherwise they would
|
* We only take multiline comments which aren't part of a batch - since otherwise they would
|
||||||
* break up the T-SQL in separate code cells and since we currently don't share state between
|
* break up the T-SQL in separate code cells and since we currently don't share state between
|
||||||
@@ -145,23 +159,28 @@ namespace Microsoft.SqlTools.ServiceLayer.NotebookConvert
|
|||||||
.Where(token => token.TokenType == TSqlTokenType.MultilineComment)
|
.Where(token => token.TokenType == TSqlTokenType.MultilineComment)
|
||||||
// Ignore comments that are within a batch. This won't include comments at the start/end of a batch though - the parser is smart enough
|
// Ignore comments that are within a batch. This won't include comments at the start/end of a batch though - the parser is smart enough
|
||||||
// to have the batch only contain the code and any comments that are embedded within it
|
// to have the batch only contain the code and any comments that are embedded within it
|
||||||
.Where(token => !batches.Any(batch => token.Offset > batch.StartOffset && token.Offset < (batch.StartOffset + batch.FragmentLength)));
|
.Where(token => !batches.Any(batch => token.Offset > batch.StartOffset && token.Offset < (batch.StartOffset + batch.FragmentLength)))
|
||||||
|
.Select(token => new NotebookToken() { StartOffset = token.Offset, Text = token.Text.Trim(), TokenType = NotebookTokenType.MultilineComment });
|
||||||
|
|
||||||
int currentIndex = 0;
|
// Combine batches and comments into a single list of all the fragments we need to add to the Notebook
|
||||||
int codeLength = 0;
|
var allFragments = batches.Select(batch =>
|
||||||
string codeBlock = "";
|
|
||||||
foreach (var comment in multilineComments)
|
|
||||||
{
|
{
|
||||||
// The code blocks are everything since the end of the last comment block up to the
|
string text = sql.Substring(batch.StartOffset, batch.FragmentLength).Trim();
|
||||||
// start of the next comment block
|
return new NotebookToken() { StartOffset = batch.StartOffset, Text = text, TokenType = NotebookTokenType.Batch };
|
||||||
codeLength = comment.Offset - currentIndex;
|
})
|
||||||
codeBlock = sql.Substring(currentIndex, codeLength).Trim();
|
.Concat(multilineComments)
|
||||||
if (!string.IsNullOrEmpty(codeBlock))
|
.OrderBy(token => token.StartOffset);
|
||||||
|
|
||||||
|
foreach (var fragment in allFragments)
|
||||||
{
|
{
|
||||||
doc.Cells.Add(GenerateCodeCell(codeBlock));
|
if (fragment.TokenType == NotebookTokenType.Batch)
|
||||||
|
{
|
||||||
|
// Batches are just simple code cells so no additional logic needed
|
||||||
|
doc.Cells.Add(GenerateCodeCell(fragment.Text));
|
||||||
}
|
}
|
||||||
|
else if (fragment.TokenType == NotebookTokenType.MultilineComment)
|
||||||
string commentBlock = comment.Text.Trim();
|
{
|
||||||
|
string commentBlock = fragment.Text;
|
||||||
// Trim off the starting comment tokens (/** or /*)
|
// Trim off the starting comment tokens (/** or /*)
|
||||||
if (commentBlock.StartsWith("/**"))
|
if (commentBlock.StartsWith("/**"))
|
||||||
{
|
{
|
||||||
@@ -182,18 +201,8 @@ namespace Microsoft.SqlTools.ServiceLayer.NotebookConvert
|
|||||||
}
|
}
|
||||||
|
|
||||||
doc.Cells.Add(GenerateMarkdownCell(commentBlock.Trim()));
|
doc.Cells.Add(GenerateMarkdownCell(commentBlock.Trim()));
|
||||||
|
|
||||||
currentIndex = comment.Offset + comment.Text.Length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add any remaining text in a final code block
|
|
||||||
codeLength = sql.Length - currentIndex;
|
|
||||||
codeBlock = sql.Substring(currentIndex, codeLength).Trim();
|
|
||||||
if (!string.IsNullOrEmpty(codeBlock))
|
|
||||||
{
|
|
||||||
doc.Cells.Add(GenerateCodeCell(codeBlock));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user