Skip to main content
Glama
cesarvarela

PostgreSQL MCP Server

by cesarvarela
test-setup.ts5.7 kB
import { beforeEach, afterEach } from 'vitest'; import { Pool } from 'pg'; import { testConnection } from '../../tools/utils'; // Global test database pool let testPool: Pool; // Initialize test pool if not already created export function getTestPool(): Pool { if (!testPool) { testPool = new Pool({ connectionString: process.env.TEST_DATABASE_URL, max: 10, // Smaller pool for testing idleTimeoutMillis: 1000, connectionTimeoutMillis: 5000, }); } return testPool; } // Clean up database state before each test beforeEach(async () => { const pool = getTestPool(); const client = await pool.connect(); try { // Drop all tables that might exist from previous tests await client.query(` DROP TABLE IF EXISTS orders CASCADE; DROP TABLE IF EXISTS products CASCADE; DROP TABLE IF EXISTS users CASCADE; DROP TABLE IF EXISTS test_types CASCADE; `); // Create fresh test tables await createTestSchema(client); } finally { client.release(); } // Initialize the global connection status for tools await testConnection(); }); // Cleanup after each test (optional - beforeEach handles it) afterEach(async () => { // Could add additional cleanup here if needed }); // Create standard test schema async function createTestSchema(client: any) { // Users table with various data types await client.query(` CREATE TABLE users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, name VARCHAR(100), age INTEGER, is_active BOOLEAN DEFAULT true, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), metadata JSONB, tags TEXT[] ) `); // Products table await client.query(` CREATE TABLE products ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, description TEXT, price DECIMAL(10,2), in_stock BOOLEAN DEFAULT true, category VARCHAR(100), tags TEXT[], attributes JSONB, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ) `); // Orders table with foreign keys await client.query(` CREATE TABLE orders ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, product_id INTEGER REFERENCES products(id) ON DELETE CASCADE, quantity INTEGER NOT NULL CHECK (quantity > 0), unit_price DECIMAL(10,2) NOT NULL, total DECIMAL(10,2) GENERATED ALWAYS AS (quantity * unit_price) STORED, status VARCHAR(50) DEFAULT 'pending', order_date TIMESTAMP WITH TIME ZONE DEFAULT NOW(), notes TEXT ) `); // Test types table for data type testing await client.query(` CREATE TABLE test_types ( id SERIAL PRIMARY KEY, text_col TEXT, int_col INTEGER, bool_col BOOLEAN, json_col JSONB, array_col TEXT[], timestamp_col TIMESTAMP WITH TIME ZONE ) `); // Create indexes for testing await client.query('CREATE INDEX idx_users_email ON users(email)'); await client.query('CREATE INDEX idx_products_category ON products(category)'); await client.query('CREATE INDEX idx_orders_user_id ON orders(user_id)'); await client.query('CREATE INDEX idx_orders_status ON orders(status)'); } // Helper function to insert test data export async function insertTestData() { const pool = getTestPool(); const client = await pool.connect(); try { // Insert test users const userResult = await client.query(` INSERT INTO users (email, name, age, is_active, metadata, tags) VALUES ('john@example.com', 'John Doe', 30, true, '{"role": "admin", "department": "IT"}', ARRAY['developer', 'admin']), ('jane@example.com', 'Jane Smith', 25, true, '{"role": "user", "department": "Sales"}', ARRAY['user']), ('bob@example.com', 'Bob Johnson', 35, false, '{"role": "user", "department": "HR"}', ARRAY['user', 'hr']) RETURNING id `); // Insert test products const productResult = await client.query(` INSERT INTO products (name, description, price, in_stock, category, tags, attributes) VALUES ('Laptop', 'High-performance laptop', 999.99, true, 'Electronics', ARRAY['computer', 'portable'], '{"brand": "TechCorp", "warranty": "2 years"}'), ('Mouse', 'Wireless optical mouse', 29.99, true, 'Electronics', ARRAY['accessory', 'wireless'], '{"brand": "TechCorp", "color": "black"}'), ('Desk', 'Standing desk', 299.99, false, 'Furniture', ARRAY['office', 'adjustable'], '{"material": "wood", "height": "adjustable"}') RETURNING id `); // Insert test orders await client.query(` INSERT INTO orders (user_id, product_id, quantity, unit_price, status, notes) VALUES ($1, $2, 1, 999.99, 'completed', 'Express delivery'), ($1, $3, 2, 29.99, 'pending', 'Standard shipping'), ($4, $2, 1, 999.99, 'cancelled', 'Changed mind') `, [ userResult.rows[0].id, // John productResult.rows[0].id, // Laptop productResult.rows[1].id, // Mouse userResult.rows[1].id, // Jane ]); return { users: userResult.rows, products: productResult.rows }; } finally { client.release(); } } // Helper function to clean database between tests export async function cleanTestData() { const pool = getTestPool(); const client = await pool.connect(); try { await client.query('TRUNCATE orders, products, users, test_types RESTART IDENTITY CASCADE'); } finally { client.release(); } } // Close test pool (for cleanup) export async function closeTestPool() { if (testPool) { await testPool.end(); } }

Latest Blog Posts

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/cesarvarela/postgres-mcp'

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