use reliable way to detect createtable statements (#19897)

* use reliable way to detect createtable statements

* PR comments

* comments
This commit is contained in:
Alan Ren
2022-06-30 18:23:12 -07:00
committed by GitHub
parent 7eed81c560
commit 9a22c429a9
8 changed files with 45 additions and 5 deletions

View File

@@ -170,4 +170,7 @@ export class DacFxTestService implements mssql.IDacFxService {
};
return Promise.resolve(streamingJobValidationResult);
}
parseTSqlScript(filePath: string, databaseSchemaProvider: string): Thenable<mssql.ParseTSqlScriptResult> {
return Promise.resolve({ containsCreateTableStatement: true });
}
}

View File

@@ -1,6 +1,6 @@
{
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
"version": "4.1.0.4",
"version": "4.1.0.9",
"downloadFileNames": {
"Windows_86": "win-x86-net6.0.zip",
"Windows_64": "win-x64-net6.0.zip",

View File

@@ -545,6 +545,11 @@ export interface ValidateStreamingJobParams {
createStreamingJobTsql: string
}
export interface ParseTSqlScriptParams {
filePath: string;
databaseSchemaProvider: string;
}
export namespace ExportRequest {
export const type = new RequestType<ExportParams, mssql.DacFxResult, void, void>('dacfx/export');
}
@@ -577,6 +582,10 @@ export namespace ValidateStreamingJobRequest {
export const type = new RequestType<ValidateStreamingJobParams, mssql.ValidateStreamingJobResult, void, void>('dacfx/validateStreamingJob');
}
export namespace ParseTSqlScriptRequest {
export const type = new RequestType<ParseTSqlScriptParams, mssql.ParseTSqlScriptResult, void, void>('dacfx/parseTSqlScript');
}
// ------------------------------- </ DacFx > ------------------------------------
// ------------------------------- <CMS> ----------------------------------------

View File

@@ -130,4 +130,15 @@ export class DacFxService implements mssql.IDacFxService {
}
);
}
public async parseTSqlScript(filePath: string, databaseSchemaProvider: string): Promise<mssql.ParseTSqlScriptResult> {
const params: contracts.ParseTSqlScriptParams = { filePath, databaseSchemaProvider };
try {
const result = await this.client.sendRequest(contracts.ParseTSqlScriptRequest.type, params);
return result;
} catch (e) {
this.client.logFailedRequest(contracts.ParseTSqlScriptRequest.type, e);
throw e;
}
}
}

View File

@@ -391,6 +391,7 @@ declare module 'mssql' {
generateDeployPlan(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<GenerateDeployPlanResult>;
getOptionsFromProfile(profilePath: string): Thenable<DacFxOptionsResult>;
validateStreamingJob(packageFilePath: string, createStreamingJobTsql: string): Thenable<ValidateStreamingJobResult>;
parseTSqlScript(filePath: string, databaseSchemaProvider: string): Thenable<ParseTSqlScriptResult>;
}
export interface DacFxResult extends azdata.ResultStatus {
@@ -408,6 +409,10 @@ declare module 'mssql' {
export interface ValidateStreamingJobResult extends azdata.ResultStatus {
}
export interface ParseTSqlScriptResult {
containsCreateTableStatement: boolean;
}
export interface ExportParams {
databaseName: string;
packageFilePath: string;

View File

@@ -10,6 +10,7 @@ import * as utils from '../common/utils';
import * as xmlFormat from 'xml-formatter';
import * as os from 'os';
import * as UUID from 'vscode-languageclient/lib/utils/uuid';
import * as mssql from 'mssql';
import { Uri, window } from 'vscode';
import { EntryType, IDatabaseReferenceProjectEntry, IProjectEntry, ISqlProject, ItemType, SqlTargetPlatform } from 'sqldbproj';
@@ -247,14 +248,19 @@ export class Project implements ISqlProject {
const fileEntries: FileProjectEntry[] = [];
for (let f of Array.from(filesSet.values())) {
const typeEntry = entriesWithType.find(e => e.relativePath === f);
let containsCreateTableStatement;
let containsCreateTableStatement = false;
// read file to check if it has a "Create Table" statement
const fullPath = path.join(utils.getPlatformSafeFileEntryPath(this.projectFolderPath), utils.getPlatformSafeFileEntryPath(f));
if (await utils.exists(fullPath)) {
const fileContents = await fs.readFile(fullPath);
containsCreateTableStatement = fileContents.toString().toLowerCase().includes('create table');
if (utils.getAzdataApi()) {
const dacFxService = await utils.getDacFxService() as mssql.IDacFxService;
try {
const result = await dacFxService.parseTSqlScript(fullPath, this.getProjectTargetVersion());
containsCreateTableStatement = result.containsCreateTableStatement;
} catch (e) {
console.error(utils.getErrorMessage(e));
}
}
fileEntries.push(this.createFileProjectEntry(f, EntryType.File, typeEntry ? typeEntry.typeAttribute : undefined, containsCreateTableStatement));

View File

@@ -140,6 +140,7 @@ export class MockDacFxService implements mssql.IDacFxService {
public generateDeployPlan(_: string, __: string, ___: string, ____: azdata.TaskExecutionMode): Thenable<mssql.GenerateDeployPlanResult> { return Promise.resolve(mockDacFxResult); }
public getOptionsFromProfile(_: string): Thenable<mssql.DacFxOptionsResult> { return Promise.resolve(mockDacFxOptionsResult); }
public validateStreamingJob(_: string, __: string): Thenable<mssql.ValidateStreamingJobResult> { return Promise.resolve(mockDacFxResult); }
public parseTSqlScript(_: string, __: string): Thenable<mssql.ParseTSqlScriptResult> { return Promise.resolve({ containsCreateTableStatement: true }); }
}
export function createContext(): TestContext {

View File

@@ -6,6 +6,7 @@
import * as path from 'path';
import * as os from 'os';
import * as constants from '../common/constants';
import * as templates from '../templates/templates';
import { promises as fs } from 'fs';
import should = require('should');
@@ -34,6 +35,10 @@ export async function createTestSqlProjFile(contents: string, folderPath?: strin
}
export async function createTestProject(contents: string, folderPath?: string): Promise<Project> {
const macroDict: Record<string, string> = {
'PROJECT_DSP': constants.defaultDSP
};
contents = templates.macroExpansion(contents, macroDict);
return await Project.openProject(await createTestSqlProjFile(contents, folderPath));
}