├── .github └── workflows │ ├── cd.yml │ └── ci.yml ├── .gitignore ├── .server.yarnrc ├── .vscodeignore ├── .yarnrc ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── ThirdPartyNotices.txt ├── gulpfile.js ├── package.json ├── src ├── connectionProvider.ts ├── index.ts └── queryProvider.ts ├── tsconfig.json ├── webpack.config.js └── yarn.lock /.github/workflows/cd.yml: -------------------------------------------------------------------------------- 1 | name: CD 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*.*.*" 7 | 8 | jobs: 9 | buildAndRelease: 10 | runs-on: ${{ matrix.os }} 11 | strategy: 12 | matrix: 13 | os: 14 | - macos-latest 15 | - ubuntu-latest 16 | - windows-2019 17 | name: ${{ matrix.os }} 18 | env: 19 | CHILD_CONCURRENCY: "1" 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | steps: 22 | - uses: actions/checkout@v4 23 | - uses: actions/setup-node@v4 24 | with: 25 | node-version: 16 26 | - uses: actions/setup-python@v5 27 | with: 28 | python-version: "3.11.x" 29 | - name: Install Dependencies 30 | run: yarn --frozen-lockfile 31 | - name: Create Package 32 | run: yarn package 33 | - name: Create Release 34 | if: startsWith(github.ref, 'refs/tags/') 35 | uses: softprops/action-gh-release@v1 36 | with: 37 | files: ./artifacts/** 38 | - name: Upload Artifacts 39 | uses: actions/upload-artifact@v4 40 | with: 41 | name: artifacts 42 | path: artifacts 43 | - name: Setup Server Package 44 | run: cp .server.yarnrc .yarnrc 45 | - name: Clean 46 | run: git clean -fxd 47 | - name: Install Dependencies (Server) 48 | run: yarn --frozen-lockfile 49 | - name: Create Package (Server) 50 | run: yarn package 51 | - name: Create Release (Server) 52 | if: startsWith(github.ref, 'refs/tags/') 53 | uses: softprops/action-gh-release@v1 54 | with: 55 | files: ./artifacts/** 56 | - name: Upload Artifacts (server) 57 | uses: actions/upload-artifact@v4 58 | with: 59 | name: artifacts (server) 60 | path: artifacts 61 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build: 12 | runs-on: ${{ matrix.os }} 13 | strategy: 14 | matrix: 15 | os: 16 | - macos-latest 17 | - ubuntu-latest 18 | - windows-2019 19 | name: ${{ matrix.os }} 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: actions/setup-node@v4 23 | with: 24 | node-version: 16 25 | - uses: actions/setup-python@v5 26 | with: 27 | python-version: "3.11.x" 28 | - name: Install Dependencies 29 | run: yarn --frozen-lockfile 30 | - name: Create Package 31 | run: yarn package 32 | - name: Setup Server Package 33 | run: cp .server.yarnrc .yarnrc 34 | - name: Clean 35 | run: git clean -fxd 36 | - name: Install Dependencies (Server) 37 | run: yarn --frozen-lockfile 38 | - name: Create Package (Server) 39 | run: yarn package 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | out 4 | artifacts 5 | *.vsix -------------------------------------------------------------------------------- /.server.yarnrc: -------------------------------------------------------------------------------- 1 | disturl "http://nodejs.org/dist" 2 | target "18.15.0" 3 | runtime "node" 4 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | src 2 | gulpfile.js 3 | .gitignore 4 | tsconfig.json 5 | webpack.config.js 6 | yarn.lock 7 | *.yarnrc 8 | .github 9 | artifacts 10 | node_modules 11 | !node_modules/sqlite3/build/Release/*.node 12 | !node_modules/sqlite3/package.json 13 | !node_modules/sqlite3/lib/sqlite3.js 14 | !node_modules/sqlite3/LICENSE 15 | out/*.map -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | disturl "https://electronjs.org/headers" 2 | target "30.5.1" 3 | runtime "electron" 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Project 2 | 3 | This project provides a SQLite connection provider for use in Azure Data Studio tests. 4 | 5 | It is currently only for testing purposes - other usage is not supported at this time. 6 | 7 | ## Creating a new Release 8 | 9 | To create a new release first update the version in [package.json](./package.json) and then create a new Release through Github targeting the main branch. The CD pipeline will automatically run and create the artifacts for that release. 10 | 11 | ## Contributing 12 | 13 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 14 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 15 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 16 | 17 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 18 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 19 | provided by the bot. You will only need to do this once across all repos using our CLA. 20 | 21 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 22 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 23 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 24 | 25 | ## Trademarks 26 | 27 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 28 | trademarks or logos is subject to and must follow 29 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 30 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 31 | Any use of third-party trademarks or logos are subject to those third-party's policies. 32 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 6 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 7 | feature request as a new Issue. 8 | 9 | For help and questions about using this project, please create a [discussion](https://github.com/microsoft/azuredatastudio-sqlite/discussions) with details about your question. 10 | 11 | ## Microsoft Support Policy 12 | 13 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above. 14 | -------------------------------------------------------------------------------- /ThirdPartyNotices.txt: -------------------------------------------------------------------------------- 1 | MICROSOFT Azure Data Studio - SQLite 2 | 3 | THIRD-PARTY SOFTWARE NOTICES AND INFORMATION 4 | Do Not Translate or Localize 5 | 6 | This project incorporates components from the projects listed below. 7 | The original copyright notices and the licenses under which Microsoft received 8 | such components are set forth below. Microsoft reserves all rights not 9 | expressly granted herein, whether by implication, estoppel or otherwise. 10 | 11 | node-sqlite3: https://github.com/mapbox/node-sqlite3 12 | 13 | %% node-sqlite3 NOTICES AND INFORMATION BEGIN HERE 14 | ================================================== 15 | Copyright (c) MapBox 16 | All rights reserved. 17 | 18 | Redistribution and use in source and binary forms, with or without modification, 19 | are permitted provided that the following conditions are met: 20 | 21 | - Redistributions of source code must retain the above copyright notice, this 22 | list of conditions and the following disclaimer. 23 | - Redistributions in binary form must reproduce the above copyright notice, this 24 | list of conditions and the following disclaimer in the documentation and/or 25 | other materials provided with the distribution. 26 | - Neither the name "MapBox" nor the names of its contributors may be 27 | used to endorse or promote products derived from this software without 28 | specific prior written permission. 29 | 30 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 31 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 32 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 33 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 34 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 35 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 36 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 37 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 39 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | ========================================= 41 | END OF node-sqlite3 NOTICES AND INFORMATION -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const rimrafcb = require('rimraf'); 3 | const webpack = require('webpack-stream'); 4 | const vsce = require('@vscode/vsce'); 5 | const zip = require('gulp-zip'); 6 | const path = require('path'); 7 | const fs = require('fs'); 8 | const rename = require('gulp-rename'); 9 | 10 | function getRuntime() { 11 | const yarnrc = fs.readFileSync(path.join(__dirname, '.yarnrc'), 'utf8'); 12 | const runtime = /^runtime "(.*)"$/m.exec(yarnrc)[1]; 13 | return runtime; 14 | } 15 | 16 | function getVersion() { 17 | const yarnrc = fs.readFileSync(path.join(__dirname, '.yarnrc'), 'utf8'); 18 | const target = /^target "(.*)"$/m.exec(yarnrc)[1]; 19 | return target; 20 | } 21 | 22 | function rimraf(path) { 23 | return new Promise((res, rej) => rimrafcb(path, e => e ? rej(e) : res())); 24 | } 25 | 26 | gulp.task('clean', () => { 27 | return Promise.all([rimraf('out'), rimraf('dist'), rimraf('*.vsix'), rimraf('*.zip')]); 28 | }); 29 | 30 | gulp.task('compile', gulp.series('clean', () => { 31 | return gulp.src('src/**') 32 | .pipe(webpack(require('./webpack.config.js'))) 33 | .pipe(gulp.dest('./out')); 34 | })); 35 | 36 | const runtime = getRuntime(); 37 | const runTimeVersion = getVersion(); 38 | const platform = process.platform; 39 | 40 | gulp.task('zip', async () => { 41 | const files = await vsce.listFiles(); 42 | return gulp.src(files, { base: './' }) 43 | .pipe(zip(`azuredatastudio-sqlite-${platform}-${runtime}-${runTimeVersion}.zip`, { })) 44 | .pipe(gulp.dest('./artifacts')); 45 | }); 46 | 47 | gulp.task('vsix', async () => { 48 | await vsce.createVSIX(); 49 | return gulp.src('*.vsix', { }) 50 | .pipe(rename(`azuredatastudio-sqlite-${platform}-${runtime}-${runTimeVersion}.vsix`)) 51 | .pipe(gulp.dest('./artifacts')); 52 | }); 53 | 54 | gulp.task('package', gulp.series('compile', gulp.parallel('zip', 'vsix'))); 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "azuredatastudio-sqlite", 3 | "displayName": "Sqlite", 4 | "description": "Provides a SQLite connection provider for use in Azure Data Studio tests", 5 | "publisher": "Microsoft", 6 | "version": "1.20.0", 7 | "main": "./out/index", 8 | "extensionKind": [ 9 | "workspace" 10 | ], 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/Microsoft/azuredatastudio-sqlite.git" 14 | }, 15 | "engines": { 16 | "vscode": "*", 17 | "azdata": "*" 18 | }, 19 | "scripts": { 20 | "test": "echo \"Error: no test specified\" && exit 1", 21 | "clean": "./node_modules/.bin/gulp clean", 22 | "compile": "./node_modules/.bin/gulp compile", 23 | "package": "./node_modules/.bin/gulp package" 24 | }, 25 | "activationEvents": [ 26 | "onConnect:sqlite" 27 | ], 28 | "author": "Microsoft", 29 | "license": "ISC", 30 | "devDependencies": { 31 | "@types/azdata": "^1.15.1", 32 | "@types/node": "12.11.7", 33 | "@vscode/vsce": "2.15.0", 34 | "azdata": "^1.0.0", 35 | "copy-webpack-plugin": "^5.1.1", 36 | "gulp": "^4.0.2", 37 | "gulp-rename": "^2.0.0", 38 | "gulp-typescript": "^6.0.0-alpha.1", 39 | "gulp-zip": "^5.0.1", 40 | "rimraf": "^3.0.2", 41 | "ts-loader": "^6.2.2", 42 | "typescript": "^3.9.0-beta", 43 | "vscode-nls-dev": "^3.3.1", 44 | "webpack": "^4.42.1", 45 | "webpack-stream": "^5.2.1" 46 | }, 47 | "dependencies": { 48 | "sqlite3": "^5.1.6-vscode" 49 | }, 50 | "resolutions": { 51 | "nan": "^2.16.0" 52 | }, 53 | "contributes": { 54 | "commands": [ 55 | { 56 | "command": "sqlite.createFile", 57 | "title": "%sqlite.createFile%" 58 | } 59 | ], 60 | "connectionProvider": { 61 | "providerId": "sqlite", 62 | "displayName": "Sqlite", 63 | "connectionOptions": [ 64 | { 65 | "specialValueType": "serverName", 66 | "isIdentity": true, 67 | "name": "file", 68 | "displayName": "File", 69 | "groupName": "Source", 70 | "valueType": "string", 71 | "defaultValue": null, 72 | "objectType": null, 73 | "categoryValues": null, 74 | "isRequired": true, 75 | "isArray": false 76 | }, 77 | { 78 | "specialValueType": "databaseName", 79 | "isIdentity": true, 80 | "name": "database", 81 | "displayName": "not used", 82 | "groupName": "Source", 83 | "valueType": "string", 84 | "defaultValue": null, 85 | "objectType": null, 86 | "categoryValues": null, 87 | "isRequired": false, 88 | "isArray": false 89 | }, 90 | { 91 | "specialValueType": "userName", 92 | "isIdentity": true, 93 | "name": "user", 94 | "displayName": "not used", 95 | "groupName": "Security", 96 | "valueType": "string", 97 | "defaultValue": null, 98 | "objectType": null, 99 | "categoryValues": null, 100 | "isRequired": false, 101 | "isArray": false 102 | }, 103 | { 104 | "specialValueType": "password", 105 | "isIdentity": true, 106 | "name": "password", 107 | "displayName": "not used", 108 | "groupName": "Security", 109 | "valueType": "password", 110 | "defaultValue": null, 111 | "objectType": null, 112 | "categoryValues": null, 113 | "isRequired": false, 114 | "isArray": false 115 | }, 116 | { 117 | "specialValueType": "connectionName", 118 | "isIdentity": true, 119 | "name": "connectionName", 120 | "displayName": "not used", 121 | "groupName": "Source", 122 | "valueType": "string", 123 | "defaultValue": null, 124 | "objectType": null, 125 | "categoryValues": null, 126 | "isRequired": false, 127 | "isArray": false 128 | } 129 | ] 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/connectionProvider.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the Source EULA. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as azdata from 'azdata'; 7 | import * as sqlite from 'sqlite3'; 8 | import * as vscode from 'vscode'; 9 | import * as path from 'path'; 10 | 11 | export class ConnectionProvider implements azdata.ConnectionProvider { 12 | public static readonly providerId = 'sqlite'; 13 | public readonly providerId = ConnectionProvider.providerId; 14 | 15 | private connectionComplete?: (connSummary: azdata.ConnectionInfoSummary) => void; 16 | 17 | public readonly databases: { [key: string]: sqlite.Database } = {}; 18 | 19 | async connect(connectionUri: string, connectionInfo: azdata.ConnectionInfo): Promise { 20 | try { 21 | let file = connectionInfo.options['file'] as string; 22 | if (!path.isAbsolute(file) && vscode.workspace.workspaceFolders?.length! > 0) { 23 | file = path.join(vscode.workspace.workspaceFolders![0].uri.fsPath, file); 24 | } 25 | await vscode.workspace.fs.stat(vscode.Uri.file(file)); 26 | this.databases[connectionUri] = new sqlite.Database(file, (err) => { 27 | if (this.connectionComplete) { 28 | if (err) { 29 | this.connectionComplete({ connectionId: connectionUri, ownerUri: connectionUri, errorMessage: err.message } as any); 30 | } else { 31 | this.connectionComplete({ connectionId: connectionUri, ownerUri: connectionUri, connectionSummary: { serverName: connectionInfo.options['file'], databaseName: connectionInfo.options['file'], userName: 'N/A' } } as any); 32 | } 33 | } 34 | }); 35 | return true; 36 | } catch (e) { 37 | return false; 38 | } 39 | } 40 | 41 | async disconnect(connectionUri: string): Promise { 42 | if (this.databases[connectionUri]) { 43 | this.databases[connectionUri].close(); 44 | delete this.databases[connectionUri]; 45 | } 46 | return true; 47 | } 48 | 49 | cancelConnect(connectionUri: string): Thenable { 50 | throw new Error('Method not implemented.'); 51 | } 52 | 53 | listDatabases(connectionUri: string): Thenable { 54 | throw new Error('Method not implemented.'); 55 | } 56 | 57 | changeDatabase(connectionUri: string, newDatabase: string): Thenable { 58 | return Promise.resolve(true); 59 | } 60 | 61 | rebuildIntelliSenseCache(connectionUri: string): Thenable { 62 | throw new Error('Method not implemented.'); 63 | } 64 | 65 | getConnectionString(connectionUri: string, includePassword: boolean): Thenable { 66 | throw new Error('Method not implemented.'); 67 | } 68 | 69 | registerOnConnectionComplete(handler: (connSummary: azdata.ConnectionInfoSummary) => any): void { 70 | this.connectionComplete = handler; 71 | } 72 | 73 | registerOnIntelliSenseCacheComplete(handler: (connectionUri: string) => any): void { 74 | // 75 | } 76 | 77 | registerOnConnectionChanged(handler: (changedConnInfo: azdata.ChangedConnectionInfo) => any): void { 78 | // 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the Source EULA. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as vscode from 'vscode'; 7 | import * as azdata from 'azdata'; 8 | import { ConnectionProvider } from './connectionProvider'; 9 | import { QueryProvider } from './queryProvider'; 10 | 11 | export async function activate(context: vscode.ExtensionContext): Promise { 12 | const connectionProvider = new ConnectionProvider(); 13 | context.subscriptions.push(azdata.dataprotocol.registerConnectionProvider(connectionProvider)); 14 | context.subscriptions.push(azdata.dataprotocol.registerQueryProvider(new QueryProvider(connectionProvider))); 15 | } 16 | 17 | export async function deactivate(): Promise { 18 | } 19 | -------------------------------------------------------------------------------- /src/queryProvider.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the Source EULA. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as azdata from 'azdata'; 7 | import { ConnectionProvider } from './connectionProvider'; 8 | import * as vscode from 'vscode'; 9 | 10 | export class QueryProvider implements azdata.QueryProvider { 11 | public static readonly providerId = 'sqlite'; 12 | public readonly providerId = QueryProvider.providerId; 13 | 14 | private queryComplete?: (result: azdata.QueryExecuteCompleteNotificationResult) => any; 15 | private onBatchStart?: (batchInfo: azdata.QueryExecuteBatchNotificationParams) => any; 16 | private onBatchComplete?: (batchInfo: azdata.QueryExecuteBatchNotificationParams) => any; 17 | private resultSetAvailable?: (resultSetInfo: azdata.QueryExecuteResultSetNotificationParams) => any; 18 | // private resultSetUpdated?: (resultSetInfo: azdata.QueryExecuteResultSetNotificationParams) => any; 19 | // private onMessage?: (message: azdata.QueryExecuteMessageParams) => any; 20 | 21 | private readonly results: { [key: string]: { [column: string]: string | number | null }[] } = {}; 22 | 23 | constructor(private readonly connections: ConnectionProvider) { 24 | 25 | } 26 | 27 | cancelQuery(ownerUri: string): Thenable { 28 | throw new Error('Method not implemented.'); 29 | } 30 | 31 | async runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions | undefined): Promise { 32 | if (this.connections.databases[ownerUri]) { 33 | // Encode the URI before parsing in case it contains reserved characters such as %20 so that the parse doesn't 34 | // parse them into their values accidently (such as if a path had %20 in the actual path name - that shouldn't be 35 | // resolved to a space) 36 | const content = (await vscode.workspace.openTextDocument(vscode.Uri.parse(encodeURI(ownerUri)))).getText(); 37 | this.connections.databases[ownerUri].all(content, (err, rows: { [column: string]: string | number | null }[]) => { 38 | this.results[ownerUri] = rows; 39 | const resultSet = { id: 0, complete: true, rowCount: rows.length, batchId: 0, columnInfo: Object.keys(rows[0]).map(v => ({ columnName: v })) }; 40 | const batchSet = { id: 0, resultSetSummaries: [resultSet] }; 41 | this.onBatchStart!({ batchSummary: { id: 0 } as any, ownerUri }); 42 | this.resultSetAvailable!({ ownerUri, resultSetSummary: resultSet as any }); 43 | this.onBatchComplete!({ batchSummary: batchSet as any, ownerUri }); 44 | this.queryComplete!({ ownerUri, batchSummaries: [batchSet] as any }); 45 | }); 46 | } else { 47 | throw new Error('Connection not found'); 48 | } 49 | } 50 | 51 | runQueryStatement(ownerUri: string, line: number, column: number): Thenable { 52 | throw new Error('Method not implemented.'); 53 | } 54 | 55 | runQueryString(ownerUri: string, queryString: string): Thenable { 56 | throw new Error('Method not implemented.'); 57 | } 58 | 59 | runQueryAndReturn(ownerUri: string, queryString: string): Thenable { 60 | throw new Error('Method not implemented.'); 61 | } 62 | 63 | parseSyntax(ownerUri: string, query: string): Thenable { 64 | throw new Error('Method not implemented.'); 65 | } 66 | 67 | async getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Promise { 68 | return { resultSubset: { rowCount: rowData.rowsCount, rows: this.results[rowData.ownerUri].map(v => Object.values(v).map(c => ({ displayValue: String(c), isNull: c === null }))) } } as any; 69 | } 70 | 71 | disposeQuery(ownerUri: string): Thenable { 72 | throw new Error('Method not implemented.'); 73 | } 74 | 75 | saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable { 76 | throw new Error('Method not implemented.'); 77 | } 78 | 79 | setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Thenable { 80 | throw new Error('Method not implemented.'); 81 | } 82 | 83 | registerOnQueryComplete(handler: (result: azdata.QueryExecuteCompleteNotificationResult) => any): void { 84 | this.queryComplete = handler; 85 | } 86 | 87 | registerOnBatchStart(handler: (batchInfo: azdata.QueryExecuteBatchNotificationParams) => any): void { 88 | this.onBatchStart = handler; 89 | } 90 | 91 | registerOnBatchComplete(handler: (batchInfo: azdata.QueryExecuteBatchNotificationParams) => any): void { 92 | this.onBatchComplete = handler; 93 | } 94 | 95 | registerOnResultSetAvailable(handler: (resultSetInfo: azdata.QueryExecuteResultSetNotificationParams) => any): void { 96 | this.resultSetAvailable = handler; 97 | } 98 | 99 | registerOnResultSetUpdated(handler: (resultSetInfo: azdata.QueryExecuteResultSetNotificationParams) => any): void { 100 | // this.resultSetUpdated = handler; 101 | } 102 | 103 | registerOnMessage(handler: (message: azdata.QueryExecuteMessageParams) => any): void { 104 | // this.onMessage = handler; 105 | } 106 | 107 | commitEdit(ownerUri: string): Thenable { 108 | throw new Error('Method not implemented.'); 109 | } 110 | 111 | createRow(ownerUri: string): Thenable { 112 | throw new Error('Method not implemented.'); 113 | } 114 | 115 | deleteRow(ownerUri: string, rowId: number): Thenable { 116 | throw new Error('Method not implemented.'); 117 | } 118 | 119 | disposeEdit(ownerUri: string): Thenable { 120 | throw new Error('Method not implemented.'); 121 | } 122 | 123 | initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable { 124 | throw new Error('Method not implemented.'); 125 | } 126 | 127 | revertCell(ownerUri: string, rowId: number, columnId: number): Thenable { 128 | throw new Error('Method not implemented.'); 129 | } 130 | 131 | revertRow(ownerUri: string, rowId: number): Thenable { 132 | throw new Error('Method not implemented.'); 133 | } 134 | 135 | updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable { 136 | throw new Error('Method not implemented.'); 137 | } 138 | 139 | getEditRows(rowData: azdata.EditSubsetParams): Thenable { 140 | throw new Error('Method not implemented.'); 141 | } 142 | 143 | registerOnEditSessionReady(handler: (ownerUri: string, success: boolean, message: string) => any): void { 144 | // 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "lib": [ 5 | "es2018" 6 | ], 7 | "module": "commonjs", 8 | "outDir": "./out", 9 | "typeRoots": [ 10 | "./node_modules/@types" 11 | ], 12 | "strict": true, 13 | "alwaysStrict": true, 14 | "noImplicitAny": true, 15 | "noImplicitReturns": true, 16 | "noUnusedLocals": true, 17 | "noUnusedParameters": false, 18 | "forceConsistentCasingInFileNames": true, 19 | "experimentalDecorators": true 20 | }, 21 | "include": [ 22 | "src/**/*" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the Source EULA. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | //@ts-check 7 | /** @typedef {import('webpack').Configuration} WebpackConfig **/ 8 | 9 | 'use strict'; 10 | 11 | const path = require('path'); 12 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 13 | const { NLSBundlePlugin } = require('vscode-nls-dev/lib/webpack-bundler'); 14 | 15 | const id = `microsoft.azuredatastudio-sqlite`; 16 | 17 | /** @type WebpackConfig */ 18 | module.exports = { 19 | mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') 20 | target: 'node', // extensions run in a node context 21 | node: { 22 | __dirname: false // leave the __dirname-behaviour intact 23 | }, 24 | resolve: { 25 | mainFields: ['module', 'main'], 26 | extensions: ['.ts', '.js'] // support ts-files and js-files 27 | }, 28 | module: { 29 | rules: [{ 30 | test: /\.ts$/, 31 | exclude: /node_modules/, 32 | use: [{ 33 | // vscode-nls-dev loader: 34 | // * rewrite nls-calls 35 | loader: 'vscode-nls-dev/lib/webpack-loader', 36 | options: { 37 | base: path.join(__dirname, 'src') 38 | } 39 | }, { 40 | // configure TypeScript loader: 41 | // * enable sources maps for end-to-end source maps 42 | loader: 'ts-loader', 43 | options: { 44 | compilerOptions: { 45 | 'sourceMap': true, 46 | } 47 | } 48 | }] 49 | }] 50 | }, 51 | externals: { 52 | 'vscode': 'commonjs vscode', // ignored because it doesn't exist 53 | 'azdata': 'commonjs azdata', 54 | 'sqlite3': 'commonjs sqlite3' 55 | }, 56 | output: { 57 | // all output goes into `dist`. 58 | // packaging depends on that and this must always be like it 59 | filename: '[name].js', 60 | path: path.join(__dirname, 'out'), 61 | libraryTarget: 'commonjs', 62 | }, 63 | // yes, really source maps 64 | devtool: 'source-map', 65 | plugins: [ 66 | // @ts-ignore 67 | new CopyWebpackPlugin([ 68 | { from: 'src', to: '.', ignore: ['**/test/**', '*.ts'] } 69 | ]), 70 | new NLSBundlePlugin(id) 71 | ], 72 | context: __dirname, 73 | entry: { 74 | index: './src/index.ts' 75 | } 76 | }; 77 | --------------------------------------------------------------------------------