Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
928a2b4
perf(ui): decouple scale preview from app-wide rebuilds (#93)
ZhuchkaTriplesix Jun 13, 2026
1114b35
perf(editor): debounce syntax highlight and always use isolate (#93)
ZhuchkaTriplesix Jun 13, 2026
301922d
perf(ui): virtualize SQL result grid (#93)
ZhuchkaTriplesix Jun 13, 2026
faf5834
perf(connections): lazy lists and sliver tree panel (#93)
ZhuchkaTriplesix Jun 13, 2026
7668cdb
fix(connections): open connection form after menu type picker
ZhuchkaTriplesix Jun 13, 2026
44bc20b
perf(ui): narrow rebuilds for splitters, panel, and forms (#93)
ZhuchkaTriplesix Jun 13, 2026
d52290e
chore(docker): add local compose stack for dev databases
ZhuchkaTriplesix Jun 13, 2026
c4f9548
feat(core): add deep collection equality helper
ZhuchkaTriplesix Jun 13, 2026
bbdabf6
perf(ui): skip postgres stats rebuild on unchanged polls
ZhuchkaTriplesix Jun 13, 2026
fe8997f
perf(editor): cache syntax highlighter pairs by theme key
ZhuchkaTriplesix Jun 13, 2026
90a355d
perf(ui): hoist SQL history preview whitespace RegExp
ZhuchkaTriplesix Jun 13, 2026
2d3d22f
perf(mysql): format SQL result rows in a worker isolate
ZhuchkaTriplesix Jun 13, 2026
bdc71f0
perf(mongo): lazy JSON cache and stable document card actions
ZhuchkaTriplesix Jun 13, 2026
7a5a7f8
fix(ui): constrain QueryaDropdown label when width is fixed
ZhuchkaTriplesix Jun 13, 2026
293ac7c
perf(redis): virtualize key member lists and fix TTL dialog lifecycle
ZhuchkaTriplesix Jun 13, 2026
fc50a95
feat(mysql): add serverStats for global status and database sizes
ZhuchkaTriplesix Jun 13, 2026
731fbb9
feat(mysql): add full server stats dashboard
ZhuchkaTriplesix Jun 13, 2026
482956e
fix(mongo): redesign stats dashboard and skip unchanged polls
ZhuchkaTriplesix Jun 13, 2026
4c1b4c3
fix(redis): redesign stats dashboard and skip unchanged polls
ZhuchkaTriplesix Jun 13, 2026
8724041
perf(redis): drop hover setState from explorer list rows
ZhuchkaTriplesix Jun 13, 2026
81ec441
perf(mongo): drop hover setState from explorer list rows
ZhuchkaTriplesix Jun 13, 2026
93e6621
fix(test): remove unnecessary string interpolation in results_tab_test
ZhuchkaTriplesix Jun 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copy to .env and adjust if host ports conflict with local services.
# cp .env.example .env

POSTGRES_PORT=5432
MYSQL_PORT=3306
REDIS_PORT=6379
MONGO_PORT=27017

POSTGRES_USER=querya
POSTGRES_PASSWORD=querya
POSTGRES_DB=querya

MYSQL_ROOT_PASSWORD=querya
MYSQL_DATABASE=querya
MYSQL_USER=querya
MYSQL_PASSWORD=querya

MONGO_INITDB_ROOT_USERNAME=querya
MONGO_INITDB_ROOT_PASSWORD=querya
142 changes: 142 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Querya Desktop — local database stack for manual testing.
#
# Start:
# cd docker && docker compose up -d
#
# Stop and remove volumes (re-run init scripts on next up):
# docker compose down -v
#
# ── Connection cheat sheet (host: localhost) ─────────────────────────────
# PostgreSQL port 5432 db querya user querya password querya
# schemas: shop.* + database analytics
# MySQL port 3306 db querya user querya password querya
# extra database: analytics
# Redis port 6379 no auth keys prefix querya:*
# MongoDB port 27017 db querya user querya password querya
# auth source: admin collections: users, products, orders
# ─────────────────────────────────────────────────────────────────────────

name: querya-dev

services:
postgres:
image: postgres:16-alpine
container_name: querya-postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-querya}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-querya}
POSTGRES_DB: ${POSTGRES_DB:-querya}
ports:
- "${POSTGRES_PORT:-5432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./postgres/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test:
[
"CMD-SHELL",
"pg_isready -U ${POSTGRES_USER:-querya} -d ${POSTGRES_DB:-querya}",
]
interval: 5s
timeout: 5s
retries: 12

mysql:
image: mysql:8.4
container_name: querya-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-querya}
MYSQL_DATABASE: ${MYSQL_DATABASE:-querya}
MYSQL_USER: ${MYSQL_USER:-querya}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-querya}
ports:
- "${MYSQL_PORT:-3306}:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d:ro
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
healthcheck:
test:
[
"CMD",
"mysqladmin",
"ping",
"-h",
"127.0.0.1",
"-u${MYSQL_USER:-querya}",
"-p${MYSQL_PASSWORD:-querya}",
]
interval: 5s
timeout: 5s
retries: 20
start_period: 30s

redis:
image: redis:7-alpine
container_name: querya-redis
restart: unless-stopped
ports:
- "${REDIS_PORT:-6379}:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 12

redis-seed:
image: redis:7-alpine
container_name: querya-redis-seed
depends_on:
redis:
condition: service_healthy
environment:
REDIS_HOST: redis
REDIS_PORT: "6379"
volumes:
- ./redis/seed.sh:/seed.sh:ro
entrypoint: ["/bin/sh", "/seed.sh"]
restart: "no"

mongo:
image: mongo:7
container_name: querya-mongo
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME:-querya}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD:-querya}
ports:
- "${MONGO_PORT:-27017}:27017"
volumes:
- mongo_data:/data/db
- ./mongo/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test:
[
"CMD",
"mongosh",
"--quiet",
"-u",
"${MONGO_INITDB_ROOT_USERNAME:-querya}",
"-p",
"${MONGO_INITDB_ROOT_PASSWORD:-querya}",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping').ok",
]
interval: 5s
timeout: 5s
retries: 20
start_period: 30s

volumes:
postgres_data:
mysql_data:
redis_data:
mongo_data:
83 changes: 83 additions & 0 deletions docker/mongo/init/01_seed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Demo data for Querya manual testing (MongoDB).
const appDb = db.getSiblingDB('querya');

appDb.users.drop();
appDb.products.drop();
appDb.orders.drop();

appDb.users.insertMany([
{
name: 'Alice Martin',
email: 'alice@example.com',
role: 'admin',
city: 'Berlin',
tags: ['staff', 'beta'],
active: true,
},
{
name: 'Bob Smith',
email: 'bob@example.com',
role: 'customer',
city: 'London',
tags: ['beta'],
active: true,
},
{
name: 'Carla Ruiz',
email: 'carla@example.com',
role: 'customer',
city: 'Madrid',
tags: [],
active: false,
},
]);

appDb.products.insertMany([
{ sku: 'SKU-001', title: 'Wireless Mouse', price: 29.99, stock: 120 },
{ sku: 'SKU-002', title: 'Mechanical Keyboard', price: 89.0, stock: 45 },
{ sku: 'SKU-003', title: 'USB-C Hub', price: 45.5, stock: 80 },
{ sku: 'SKU-004', title: '27" Monitor', price: 329.0, stock: 15 },
]);

appDb.orders.insertMany([
{
customerEmail: 'alice@example.com',
status: 'paid',
total: 164.49,
placedAt: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000),
lines: [
{ sku: 'SKU-001', qty: 1, unitPrice: 29.99 },
{ sku: 'SKU-003', qty: 1, unitPrice: 45.5 },
{ sku: 'SKU-002', qty: 1, unitPrice: 89.0 },
],
},
{
customerEmail: 'bob@example.com',
status: 'shipped',
total: 404.0,
placedAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000),
lines: [{ sku: 'SKU-004', qty: 1, unitPrice: 329.0 }],
},
{
customerEmail: 'carla@example.com',
status: 'new',
total: 29.99,
placedAt: new Date(),
lines: [{ sku: 'SKU-001', qty: 1, unitPrice: 29.99 }],
},
]);

appDb.users.createIndex({ email: 1 }, { unique: true });
appDb.products.createIndex({ sku: 1 }, { unique: true });
appDb.orders.createIndex({ status: 1, placedAt: -1 });

const analyticsDb = db.getSiblingDB('analytics');
analyticsDb.metrics.drop();
analyticsDb.metrics.insertMany([
{ day: new Date(), orders: 4, revenue: 203.99 },
{
day: new Date(Date.now() - 24 * 60 * 60 * 1000),
orders: 9,
revenue: 615.0,
},
]);
87 changes: 87 additions & 0 deletions docker/mysql/init/01_shop.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
-- Demo schema for Querya manual testing (MySQL / MariaDB-compatible).
USE querya;

CREATE TABLE customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(120) NOT NULL,
email VARCHAR(160) NOT NULL UNIQUE,
city VARCHAR(80),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
sku VARCHAR(32) NOT NULL UNIQUE,
title VARCHAR(160) NOT NULL,
price DECIMAL(10, 2) NOT NULL
) ENGINE=InnoDB;

CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT NOT NULL,
status VARCHAR(32) NOT NULL DEFAULT 'new',
total DECIMAL(10, 2) NOT NULL DEFAULT 0,
placed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers (id)
) ENGINE=InnoDB;

CREATE TABLE order_lines (
order_id INT NOT NULL,
product_id INT NOT NULL,
qty INT NOT NULL,
unit_price DECIMAL(10, 2) NOT NULL,
PRIMARY KEY (order_id, product_id),
CONSTRAINT fk_lines_order FOREIGN KEY (order_id) REFERENCES orders (id) ON DELETE CASCADE,
CONSTRAINT fk_lines_product FOREIGN KEY (product_id) REFERENCES products (id)
) ENGINE=InnoDB;

INSERT INTO customers (name, email, city) VALUES
('Alice Martin', 'alice@example.com', 'Berlin'),
('Bob Smith', 'bob@example.com', 'London'),
('Carla Ruiz', 'carla@example.com', 'Madrid');

INSERT INTO products (sku, title, price) VALUES
('SKU-001', 'Wireless Mouse', 29.99),
('SKU-002', 'Mechanical Keyboard', 89.00),
('SKU-003', 'USB-C Hub', 45.50),
('SKU-004', '27 inch Monitor', 329.00);

INSERT INTO orders (customer_id, status, total, placed_at) VALUES
(1, 'paid', 164.49, NOW() - INTERVAL 2 DAY),
(2, 'shipped', 404.49, NOW() - INTERVAL 1 DAY),
(3, 'new', 29.99, NOW());

INSERT INTO order_lines (order_id, product_id, qty, unit_price) VALUES
(1, 1, 1, 29.99),
(1, 3, 1, 45.50),
(1, 2, 1, 89.00),
(2, 4, 1, 329.00),
(2, 1, 1, 29.99),
(2, 3, 1, 45.50),
(3, 1, 1, 29.99);

CREATE VIEW customer_spending AS
SELECT
c.id,
c.name,
c.city,
COUNT(o.id) AS order_count,
COALESCE(SUM(o.total), 0) AS lifetime_total
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.name, c.city;

CREATE DATABASE IF NOT EXISTS analytics;

USE analytics;

CREATE TABLE daily_sales (
day DATE PRIMARY KEY,
orders INT NOT NULL,
revenue DECIMAL(12, 2) NOT NULL
) ENGINE=InnoDB;

INSERT INTO daily_sales (day, orders, revenue) VALUES
(CURDATE() - INTERVAL 2 DAY, 12, 842.50),
(CURDATE() - INTERVAL 1 DAY, 9, 615.00),
(CURDATE(), 4, 203.99);
Loading
Loading