Skip to main content
Glama

DevDb MCP Server

mssql.test.ts7.74 kB
import * as assert from 'assert'; import knexlib from "knex"; import { MSSQLServerContainer, StartedMSSQLServerContainer } from '@testcontainers/mssqlserver'; import { MssqlEngine } from '../../../database-engines/mssql-engine'; import { SerializedMutation } from '../../../types'; /** * We use a predefined image like this because docker image download can be ery very slow, hence * on new computer/initial setup when the image is not already existing, it takes a very long time * to run this test. Using a predefined image name like this makes it possible to us to manually * download the image (e.g. using `docker run ...`) to ensure it exists in the system before running the test. */ const dockerImage = 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' describe('MSSQL Tests', () => { let container: StartedMSSQLServerContainer; before(async function () { container = await new MSSQLServerContainer(dockerImage) .withName('devdb-test-container-mssql') .acceptLicense() .withPassword('yourStrong(!)Password') .withReuse() .start(); }) it('should return foreign key definitions', async () => { const connection = knexlib.knex({ client: 'mssql', connection: { host: container.getHost(), port: container.getMappedPort(1433), database: 'master', user: 'sa', password: 'yourStrong(!)Password', } }); await connection?.raw(`DROP TABLE IF EXISTS ChildTable`); await connection?.raw(`DROP TABLE IF EXISTS ParentTable`); await connection.raw(` CREATE TABLE ParentTable ( id INT PRIMARY KEY IDENTITY(1,1) ) `); await connection.raw(` CREATE TABLE ChildTable ( id INT PRIMARY KEY IDENTITY(1,1), parentId INT, FOREIGN KEY (parentId) REFERENCES ParentTable(id) ) `); const mssql = new MssqlEngine(connection); const columns = await mssql.getColumns('ChildTable'); const foreignKeyColumn = columns.find(column => column.name === 'parentId'); assert.strictEqual(foreignKeyColumn?.foreignKey?.table, 'ParentTable'); await mssql.connection?.raw(`DROP TABLE IF EXISTS ChildTable`); await mssql.connection?.raw(`DROP TABLE IF EXISTS ParentTable`); await connection.destroy(); }) describe('MssqlEngine Tests', () => { let engine: MssqlEngine; before(async function () { const connection = knexlib.knex({ client: 'mssql', connection: { host: container.getHost(), port: container.getMappedPort(1433), database: 'master', user: 'sa', password: 'yourStrong(!)Password', } }); engine = new MssqlEngine(connection); const ok = await engine.isOkay(); assert.strictEqual(ok, true); }) beforeEach(async function () { await engine.connection?.raw(`DROP TABLE IF EXISTS products`); await engine.connection?.raw(`DROP TABLE IF EXISTS users`); await engine.connection?.raw(` CREATE TABLE users ( id INT PRIMARY KEY IDENTITY(1,1), name varchar(255), age INT ) `); }); afterEach(async function () { await engine.connection?.raw(`DROP TABLE IF EXISTS users`); await engine.connection?.raw(`DROP TABLE IF EXISTS products`); }) it('should return table names', async () => { await engine.connection?.raw(` CREATE TABLE products ( id INT PRIMARY KEY, name varchar(255), price INT ) `); const tables = await engine.getTables(); assert.deepStrictEqual(tables, ['products', 'users']); }) ; it('should return column definitions', async () => { const columns = await engine.getColumns('users'); assert.deepStrictEqual(columns, [ { name: 'id', type: 'int', isPrimaryKey: true, isNumeric: true, isNullable: false, foreignKey: undefined, isEditable: true, isPlainTextType: false, }, { name: 'name', type: 'varchar', isPrimaryKey: false, isNumeric: false, isNullable: true, foreignKey: undefined, isEditable: true, isPlainTextType: true, }, { name: 'age', type: 'int', isPrimaryKey: false, isNumeric: true, isNullable: true, foreignKey: undefined, isEditable: true, isPlainTextType: false, } ]); }) ; it('should return total rows', async () => { await engine.connection?.raw(` INSERT INTO users (name, age) VALUES ('John', 30), ('Jane', 25), ('Bob', 40) `); const totalRows = await engine.getTotalRows('users', []); assert.strictEqual(totalRows, 3); }) ; it('should return rows', async () => { await engine.connection?.raw(` INSERT INTO users (name, age) VALUES ('John', 30), ('Jane', 25), ('Bob', 40) `); const rows = await engine.getRows('users', [], 2, 0); assert.deepStrictEqual(rows?.rows, [ { id: 1, name: 'John', age: 30 }, { id: 2, name: 'Jane', age: 25 } ]); }) ; it('should save changes', async () => { await engine.connection?.raw(` INSERT INTO users (name, age) VALUES ('John', 30) `); const mutation: SerializedMutation = { type: 'cell-update', id: '1', tabId: 'abc', column: { name: 'age', type: 'int', isPlainTextType: true, isNumeric: true, isNullable: true, isEditable: false, isPrimaryKey: false }, newValue: 31, primaryKey: 1, primaryKeyColumn: 'id', table: 'users' }; await engine.commitChange(mutation, await engine.connection?.transaction()!); const rows = await engine.getRows('users', [], 1, 0); assert.strictEqual(rows?.rows[0].age, 31); }); it('should return table creation SQL', async () => { const creationSql = (await engine.getTableCreationSql('users')) .replace(/\[|\]/g, '') .replace(/\n|\t/g, '') .replace(/\s+/g, ' ') .trim(); assert.strictEqual(creationSql, '{ "TABLE_QUALIFIER": "master", "TABLE_OWNER": "dbo", "TABLE_NAME": "users", "COLUMN_NAME": "id", "DATA_TYPE": 4, "TYPE_NAME": "int identity", "PRECISION": 10, "LENGTH": 4, "SCALE": 0, "RADIX": 10, "NULLABLE": 0, "REMARKS": null, "COLUMN_DEF": null, "SQL_DATA_TYPE": 4, "SQL_DATETIME_SUB": null, "CHAR_OCTET_LENGTH": null, "ORDINAL_POSITION": 1, "IS_NULLABLE": "NO", "SS_DATA_TYPE": 56 }, { "TABLE_QUALIFIER": "master", "TABLE_OWNER": "dbo", "TABLE_NAME": "users", "COLUMN_NAME": "name", "DATA_TYPE": 12, "TYPE_NAME": "varchar", "PRECISION": 255, "LENGTH": 255, "SCALE": null, "RADIX": null, "NULLABLE": 1, "REMARKS": null, "COLUMN_DEF": null, "SQL_DATA_TYPE": 12, "SQL_DATETIME_SUB": null, "CHAR_OCTET_LENGTH": 255, "ORDINAL_POSITION": 2, "IS_NULLABLE": "YES", "SS_DATA_TYPE": 39 }, { "TABLE_QUALIFIER": "master", "TABLE_OWNER": "dbo", "TABLE_NAME": "users", "COLUMN_NAME": "age", "DATA_TYPE": 4, "TYPE_NAME": "int", "PRECISION": 10, "LENGTH": 4, "SCALE": 0, "RADIX": 10, "NULLABLE": 1, "REMARKS": null, "COLUMN_DEF": null, "SQL_DATA_TYPE": 4, "SQL_DATETIME_SUB": null, "CHAR_OCTET_LENGTH": null, "ORDINAL_POSITION": 3, "IS_NULLABLE": "YES", "SS_DATA_TYPE": 38 }'); }); it('should return rows with a where clause', async () => { await engine.connection?.raw(` INSERT INTO users (name, age) VALUES ('John', 30), ('Jane', 25), ('Bob', 40), ('Alice', 30) `); const whereClause = { age: 30, name: 'John' } const rows = await engine.getRows('users', [], 10, 0, whereClause); assert.strictEqual(rows?.rows.length, 1); assert.deepStrictEqual(rows?.rows[0], { id: 1, name: 'John', age: 30 }); }); it('should return version information', async () => { const version = await engine.getVersion(); assert.strictEqual(version, undefined); }); after(async function () { await engine.connection?.destroy(); }); }) });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/damms005/devdb-vscode'

If you have feedback or need assistance with the MCP directory API, please join our Discord server