diff --git a/CHANGELOG.md b/CHANGELOG.md
index c1ea48b..59c2918 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,7 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- **Rebranded to NexQL** — Complete rebranding from PostgreSQL Explorer (YAPE) to **NexQL - postgres explorer**.
- Updated all extension icons, assets, extension configurations, display names, and marketplace metadata.
- - Redesigned the project website/documentation page at [docs/index.html](file:///home/ric-v/projects/ric-v/PgStudio/docs/index.html) and [nexql.html](file:///home/ric-v/projects/ric-v/PgStudio/nexql.html) featuring a beautiful dark layout with a new spectrum color palette (blue → indigo → magenta → amber) and interactive product tour.
+ - Redesigned the project website/documentation page at [docs/index.html](file:///home/ric-v/projects/ric-v/NexQL/docs/index.html) and [nexql.html](file:///home/ric-v/projects/ric-v/NexQL/nexql.html) featuring a beautiful dark layout with a new spectrum color palette (blue → indigo → magenta → amber) and interactive product tour.
### Added
@@ -265,7 +265,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
NexQL v1.0.0 is a major milestone release with comprehensive stability improvements, security hardening, and production-ready tooling.
#### Added
-- **DDL Viewer SQL Preview toggle**: Added user-facing toggle command and setting (`pgstudio.ddlViewer.enabled`) to quickly enable/disable definition preview actions.
+- **DDL Viewer SQL Preview toggle**: Added user-facing toggle command and setting (`nexql.ddlViewer.enabled`) to quickly enable/disable definition preview actions.
- **Definition Viewer workflow actions**: Improved DDL viewer command surface for opening editable copies, copying SQL, and routine execution scaffolding.
#### Changed
diff --git a/MARKETPLACE.md b/MARKETPLACE.md
index 683f483..05d4c1d 100644
--- a/MARKETPLACE.md
+++ b/MARKETPLACE.md
@@ -158,7 +158,7 @@ NexQL connects to **any PostgreSQL-wire-compatible database**:
- ✅ **YugabyteDB** (YSQL) — distributed Postgres, port 5433
- ✅ **AWS RDS / Aurora**, **Google Cloud SQL / AlloyDB**, **Azure Database for PostgreSQL**
-See the [compatibility guide](https://github.com/dev-asterix/PgStudio/blob/main/docs/COMPATIBILITY.md) for per-platform connection settings and caveats.
+See the [compatibility guide](https://github.com/dev-asterix/NexQL/blob/main/docs/COMPATIBILITY.md) for per-platform connection settings and caveats.
---
@@ -284,15 +284,15 @@ code --install-extension ric-v.postgres-explorer
## 📚 Resources
- 📖 [Full Documentation](https://nexql.astrx.dev/)
-- 🐛 [Report Issues](https://github.com/dev-asterix/PgStudio/issues)
-- 💡 [Request Features](https://github.com/dev-asterix/PgStudio/issues/new?template=feature_request.md)
-- ⭐ [Star on GitHub](https://github.com/dev-asterix/PgStudio)
+- 🐛 [Report Issues](https://github.com/dev-asterix/NexQL/issues)
+- 💡 [Request Features](https://github.com/dev-asterix/NexQL/issues/new?template=feature_request.md)
+- ⭐ [Star on GitHub](https://github.com/dev-asterix/NexQL)
---
## 📝 License
-This extension is licensed under the [MIT License](https://github.com/dev-asterix/PgStudio/blob/main/LICENSE).
+This extension is licensed under the [MIT License](https://github.com/dev-asterix/NexQL/blob/main/LICENSE).
---
diff --git a/README.md b/README.md
index 9667d3b..6b59510 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
[](https://marketplace.visualstudio.com/items?itemName=ric-v.postgres-explorer)
[](https://marketplace.visualstudio.com/items?itemName=ric-v.postgres-explorer)
[](https://marketplace.visualstudio.com/items?itemName=ric-v.postgres-explorer)
-[](https://github.com/dev-asterix/PgStudio/releases)
+[](https://github.com/dev-asterix/NexQL/releases)
**NexQL** (formerly YAPE) is a comprehensive PostgreSQL database management extension featuring interactive SQL notebooks, real-time monitoring dashboard, AI-powered assistance, and advanced database operations—all within VS Code.
@@ -360,7 +360,7 @@ Turn any query result into beautiful, interactive charts in seconds.
```bash
# Clone the repository
-git clone https://github.com/dev-asterix/PgStudio.git
+git clone https://github.com/dev-asterix/NexQL.git
cd NexQL
# Install dependencies
@@ -472,8 +472,8 @@ NexQL includes comprehensive testing infrastructure:
## 🤝 Contributing
-- 🐛 [Report Bugs](https://github.com/dev-asterix/PgStudio/issues/new?template=bug_report.md)
-- 💡 [Request Features](https://github.com/dev-asterix/PgStudio/issues/new?template=feature_request.md)
+- 🐛 [Report Bugs](https://github.com/dev-asterix/NexQL/issues/new?template=bug_report.md)
+- 💡 [Request Features](https://github.com/dev-asterix/NexQL/issues/new?template=feature_request.md)
- 🔧 Fork → Branch → PR
- 🧪 Ensure all tests pass: `npm run test:all && npm run coverage`
diff --git a/api/_lib/email.js b/api/_lib/email.js
index 0c998b1..8424184 100644
--- a/api/_lib/email.js
+++ b/api/_lib/email.js
@@ -4,7 +4,7 @@
const https = require('https');
-const FROM = process.env.LICENSE_EMAIL_FROM || 'PgStudio ';
+const FROM = process.env.LICENSE_EMAIL_FROM || 'NexQL ';
function activateUri(licenseKey) {
return `vscode://ric-v.postgres-explorer/activate?key=${encodeURIComponent(licenseKey)}`;
@@ -14,13 +14,13 @@ function buildHtml(licenseKey, tier) {
const tierName = tier ? tier[0].toUpperCase() + tier.slice(1) : 'Pro';
return `
-
Welcome to PgStudio ${tierName} 🎉
+
Welcome to NexQL ${tierName} 🎉
Your license key:
${licenseKey}
Activate in VS Code
-
Or run PgStudio: Activate License from the command palette and paste the key above.
+
Or run NexQL: Activate License from the command palette and paste the key above.
`;
}
@@ -35,7 +35,7 @@ function sendLicenseEmail(to, licenseKey, tier) {
const payload = JSON.stringify({
from: FROM,
to: [to],
- subject: 'Your PgStudio license key',
+ subject: 'Your NexQL license key',
html: buildHtml(licenseKey, tier),
});
diff --git a/api/_lib/license-db.js b/api/_lib/license-db.js
index 84570d8..033ef8b 100644
--- a/api/_lib/license-db.js
+++ b/api/_lib/license-db.js
@@ -75,9 +75,9 @@ async function ensureSchema() {
if (!schemaReady) {
schemaReady = (async () => {
const db = getSql();
- await db`CREATE SCHEMA IF NOT EXISTS pgstudio_license`;
+ await db`CREATE SCHEMA IF NOT EXISTS nexql_license`;
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_license.licenses (
+ CREATE TABLE IF NOT EXISTS nexql_license.licenses (
license_key TEXT PRIMARY KEY,
tier TEXT NOT NULL CHECK (tier IN ('sponsor','singularity')),
period TEXT NOT NULL DEFAULT 'monthly',
@@ -93,11 +93,11 @@ async function ensureSchema() {
`;
await db`
CREATE INDEX IF NOT EXISTS licenses_email_idx
- ON pgstudio_license.licenses (lower(email))
+ ON nexql_license.licenses (lower(email))
`;
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_license.devices (
- license_key TEXT NOT NULL REFERENCES pgstudio_license.licenses(license_key),
+ CREATE TABLE IF NOT EXISTS nexql_license.devices (
+ license_key TEXT NOT NULL REFERENCES nexql_license.licenses(license_key),
instance_id TEXT NOT NULL,
device_name TEXT,
first_seen TIMESTAMPTZ NOT NULL DEFAULT now(),
@@ -107,7 +107,7 @@ async function ensureSchema() {
)
`;
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_license.license_events (
+ CREATE TABLE IF NOT EXISTS nexql_license.license_events (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
license_key TEXT NOT NULL,
event_type TEXT NOT NULL,
@@ -118,10 +118,10 @@ async function ensureSchema() {
`;
await db`
CREATE INDEX IF NOT EXISTS license_events_key_created_idx
- ON pgstudio_license.license_events (license_key, created_at DESC)
+ ON nexql_license.license_events (license_key, created_at DESC)
`;
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_license.webhook_events (
+ CREATE TABLE IF NOT EXISTS nexql_license.webhook_events (
razorpay_event_id TEXT PRIMARY KEY,
received_at TIMESTAMPTZ NOT NULL DEFAULT now()
)
@@ -137,7 +137,7 @@ async function fetchLicenseRow(licenseKey) {
const key = normalizeKey(licenseKey);
const rows = await db`
SELECT *
- FROM pgstudio_license.licenses
+ FROM nexql_license.licenses
WHERE license_key = ${key}
LIMIT 1
`;
@@ -150,7 +150,7 @@ async function fetchDeviceRows(licenseKey) {
const key = normalizeKey(licenseKey);
return db`
SELECT instance_id, device_name, first_seen, last_seen, revoked_at
- FROM pgstudio_license.devices
+ FROM nexql_license.devices
WHERE license_key = ${key}
ORDER BY last_seen DESC
`;
@@ -169,7 +169,7 @@ async function getLicenseBySubscription(subscriptionId) {
const db = getSql();
const rows = await db`
SELECT license_key
- FROM pgstudio_license.licenses
+ FROM nexql_license.licenses
WHERE subscription_id = ${subscriptionId}
LIMIT 1
`;
@@ -184,7 +184,7 @@ async function getLicenseByEmail(email) {
const db = getSql();
const rows = await db`
SELECT license_key
- FROM pgstudio_license.licenses
+ FROM nexql_license.licenses
WHERE lower(email) = ${norm}
ORDER BY updated_at DESC
LIMIT 1
@@ -197,7 +197,7 @@ async function appendEvent(licenseKey, eventType, detail, source) {
await ensureSchema();
const db = getSql();
await db`
- INSERT INTO pgstudio_license.license_events (license_key, event_type, detail, source)
+ INSERT INTO nexql_license.license_events (license_key, event_type, detail, source)
VALUES (
${normalizeKey(licenseKey)},
${eventType},
@@ -212,7 +212,7 @@ async function countRenewals(licenseKey) {
const db = getSql();
const rows = await db`
SELECT COUNT(*)::int AS n
- FROM pgstudio_license.license_events
+ FROM nexql_license.license_events
WHERE license_key = ${normalizeKey(licenseKey)}
AND event_type IN ('renewed', 'expiry_extended')
`;
@@ -224,7 +224,7 @@ async function getRecentEvents(licenseKey, limit = 50) {
const db = getSql();
const rows = await db`
SELECT event_type, detail, source, created_at
- FROM pgstudio_license.license_events
+ FROM nexql_license.license_events
WHERE license_key = ${normalizeKey(licenseKey)}
ORDER BY created_at DESC
LIMIT ${limit}
@@ -242,7 +242,7 @@ async function recordWebhookEvent(razorpayEventId) {
await ensureSchema();
const db = getSql();
const rows = await db`
- INSERT INTO pgstudio_license.webhook_events (razorpay_event_id)
+ INSERT INTO nexql_license.webhook_events (razorpay_event_id)
VALUES (${razorpayEventId})
ON CONFLICT (razorpay_event_id) DO NOTHING
RETURNING razorpay_event_id
@@ -258,7 +258,7 @@ async function syncDevicesFromEntitlement(licenseKey, instanceIds) {
const db = getSql();
for (const instanceId of ids) {
await db`
- INSERT INTO pgstudio_license.devices (license_key, instance_id, last_seen, revoked_at)
+ INSERT INTO nexql_license.devices (license_key, instance_id, last_seen, revoked_at)
VALUES (${key}, ${instanceId}, now(), NULL)
ON CONFLICT (license_key, instance_id) DO UPDATE SET
last_seen = now(),
@@ -283,7 +283,7 @@ async function upsertLicense(entitlement, meta = {}) {
const createdAt = msToIso(ent.createdAt) || (existing && existing.created_at) || new Date().toISOString();
await db`
- INSERT INTO pgstudio_license.licenses (
+ INSERT INTO nexql_license.licenses (
license_key, tier, period, currency, status, subscription_id, email,
expires_at, created_at, updated_at
)
@@ -304,8 +304,8 @@ async function upsertLicense(entitlement, meta = {}) {
period = EXCLUDED.period,
currency = EXCLUDED.currency,
status = EXCLUDED.status,
- subscription_id = COALESCE(EXCLUDED.subscription_id, pgstudio_license.licenses.subscription_id),
- email = COALESCE(EXCLUDED.email, pgstudio_license.licenses.email),
+ subscription_id = COALESCE(EXCLUDED.subscription_id, nexql_license.licenses.subscription_id),
+ email = COALESCE(EXCLUDED.email, nexql_license.licenses.email),
expires_at = EXCLUDED.expires_at,
updated_at = now()
`;
@@ -359,7 +359,7 @@ async function countActiveDevices(licenseKey) {
const db = getSql();
const rows = await db`
SELECT COUNT(*)::int AS n
- FROM pgstudio_license.devices
+ FROM nexql_license.devices
WHERE license_key = ${normalizeKey(licenseKey)}
AND revoked_at IS NULL
`;
@@ -371,7 +371,7 @@ async function isDeviceActive(licenseKey, instanceId) {
const db = getSql();
const rows = await db`
SELECT 1
- FROM pgstudio_license.devices
+ FROM nexql_license.devices
WHERE license_key = ${normalizeKey(licenseKey)}
AND instance_id = ${instanceId}
AND revoked_at IS NULL
@@ -388,7 +388,7 @@ async function bindDevice(licenseKey, instanceId, meta = {}) {
const db = getSql();
const existing = await db`
SELECT instance_id, revoked_at, last_seen
- FROM pgstudio_license.devices
+ FROM nexql_license.devices
WHERE license_key = ${key} AND instance_id = ${instanceId}
LIMIT 1
`;
@@ -397,14 +397,14 @@ async function bindDevice(licenseKey, instanceId, meta = {}) {
const isNew = existing.length === 0;
await db`
- INSERT INTO pgstudio_license.devices (license_key, instance_id, device_name, last_seen, revoked_at)
+ INSERT INTO nexql_license.devices (license_key, instance_id, device_name, last_seen, revoked_at)
VALUES (${key}, ${instanceId}, ${meta.deviceName || null}, now(), NULL)
ON CONFLICT (license_key, instance_id) DO UPDATE SET
last_seen = now(),
revoked_at = NULL,
device_name = CASE
WHEN EXCLUDED.device_name IS NOT NULL THEN EXCLUDED.device_name
- ELSE pgstudio_license.devices.device_name
+ ELSE nexql_license.devices.device_name
END
`;
@@ -428,7 +428,7 @@ async function removeDevice(licenseKey, instanceId, meta = {}) {
await ensureSchema();
const db = getSql();
const rows = await db`
- UPDATE pgstudio_license.devices
+ UPDATE nexql_license.devices
SET revoked_at = now()
WHERE license_key = ${key}
AND instance_id = ${instanceId}
@@ -447,7 +447,7 @@ async function listActiveDevicesOldestFirst(licenseKey) {
const db = getSql();
const rows = await db`
SELECT instance_id, device_name, first_seen, last_seen
- FROM pgstudio_license.devices
+ FROM nexql_license.devices
WHERE license_key = ${normalizeKey(licenseKey)}
AND revoked_at IS NULL
ORDER BY last_seen ASC NULLS FIRST, first_seen ASC
@@ -489,7 +489,7 @@ async function listActiveDevices(licenseKey) {
const db = getSql();
const rows = await db`
SELECT instance_id, device_name, first_seen, last_seen
- FROM pgstudio_license.devices
+ FROM nexql_license.devices
WHERE license_key = ${normalizeKey(licenseKey)}
AND revoked_at IS NULL
ORDER BY last_seen DESC
@@ -506,7 +506,7 @@ async function expirePastDueLicenses() {
await ensureSchema();
const db = getSql();
const rows = await db`
- UPDATE pgstudio_license.licenses
+ UPDATE nexql_license.licenses
SET status = 'expired', updated_at = now()
WHERE status = 'active'
AND expires_at IS NOT NULL
diff --git a/api/_lib/store.js b/api/_lib/store.js
index 93f0d12..a4ef79c 100644
--- a/api/_lib/store.js
+++ b/api/_lib/store.js
@@ -1,6 +1,6 @@
// Entitlement store abstraction.
//
-// Primary store: Neon Postgres (pgstudio_license schema) when DATABASE_URL is set.
+// Primary store: Neon Postgres (nexql_license schema) when DATABASE_URL is set.
// Legacy dual-write: Vercel KV (Upstash Redis) when KV_REST_API_URL is present.
// Dev fallback: local JSON file (.kv-dev.json at repo root) when neither is configured.
//
diff --git a/api/_lib/sync-db.js b/api/_lib/sync-db.js
index 5b5c37b..df6c657 100644
--- a/api/_lib/sync-db.js
+++ b/api/_lib/sync-db.js
@@ -29,10 +29,10 @@ async function ensureSchema() {
if (!schemaReady) {
schemaReady = (async () => {
const db = getSql();
- await db`CREATE SCHEMA IF NOT EXISTS pgstudio_sync`;
- await db`CREATE SEQUENCE IF NOT EXISTS pgstudio_sync.cursor_seq`;
+ await db`CREATE SCHEMA IF NOT EXISTS nexql_sync`;
+ await db`CREATE SEQUENCE IF NOT EXISTS nexql_sync.cursor_seq`;
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_sync.items_v2 (
+ CREATE TABLE IF NOT EXISTS nexql_sync.items_v2 (
space_id TEXT NOT NULL,
item_id TEXT NOT NULL,
kind TEXT NOT NULL CHECK (kind IN ('connection','query','notebook')),
@@ -46,11 +46,11 @@ async function ensureSchema() {
`;
await db`
CREATE INDEX IF NOT EXISTS items_v2_cursor_idx
- ON pgstudio_sync.items_v2 (space_id, version)
+ ON nexql_sync.items_v2 (space_id, version)
`;
// Permanent delete log — never pruned. Stops deleted items resurrecting.
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_sync.deletes_v2 (
+ CREATE TABLE IF NOT EXISTS nexql_sync.deletes_v2 (
space_id TEXT NOT NULL,
item_id TEXT NOT NULL,
version BIGINT NOT NULL,
@@ -61,11 +61,11 @@ async function ensureSchema() {
`;
await db`
CREATE INDEX IF NOT EXISTS deletes_v2_cursor_idx
- ON pgstudio_sync.deletes_v2 (space_id, version)
+ ON nexql_sync.deletes_v2 (space_id, version)
`;
// Shared workspaces (team sharing). Personal space rows are implicit.
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_sync.spaces (
+ CREATE TABLE IF NOT EXISTS nexql_sync.spaces (
space_id TEXT PRIMARY KEY,
name TEXT NOT NULL,
owner_email TEXT NOT NULL,
@@ -73,8 +73,8 @@ async function ensureSchema() {
)
`;
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_sync.space_members (
- space_id TEXT NOT NULL REFERENCES pgstudio_sync.spaces(space_id) ON DELETE CASCADE,
+ CREATE TABLE IF NOT EXISTS nexql_sync.space_members (
+ space_id TEXT NOT NULL REFERENCES nexql_sync.spaces(space_id) ON DELETE CASCADE,
email TEXT NOT NULL,
role TEXT NOT NULL CHECK (role IN ('owner','editor','viewer')),
added_at TIMESTAMPTZ NOT NULL DEFAULT now(),
@@ -82,7 +82,7 @@ async function ensureSchema() {
)
`;
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_sync.sync_accounts (
+ CREATE TABLE IF NOT EXISTS nexql_sync.sync_accounts (
account_id TEXT PRIMARY KEY,
tier TEXT NOT NULL DEFAULT 'sponsor',
bytes_used BIGINT NOT NULL DEFAULT 0,
@@ -93,13 +93,13 @@ async function ensureSchema() {
`;
// Migrate sync_accounts created by older deploys — CREATE TABLE IF NOT EXISTS
// never alters an existing table, so newer columns must be added explicitly.
- await db`ALTER TABLE pgstudio_sync.sync_accounts ADD COLUMN IF NOT EXISTS tier TEXT NOT NULL DEFAULT 'sponsor'`;
- await db`ALTER TABLE pgstudio_sync.sync_accounts ADD COLUMN IF NOT EXISTS bytes_used BIGINT NOT NULL DEFAULT 0`;
- await db`ALTER TABLE pgstudio_sync.sync_accounts ADD COLUMN IF NOT EXISTS item_count INT NOT NULL DEFAULT 0`;
- await db`ALTER TABLE pgstudio_sync.sync_accounts ADD COLUMN IF NOT EXISTS inactive_since TIMESTAMPTZ`;
- await db`ALTER TABLE pgstudio_sync.sync_accounts ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT now()`;
+ await db`ALTER TABLE nexql_sync.sync_accounts ADD COLUMN IF NOT EXISTS tier TEXT NOT NULL DEFAULT 'sponsor'`;
+ await db`ALTER TABLE nexql_sync.sync_accounts ADD COLUMN IF NOT EXISTS bytes_used BIGINT NOT NULL DEFAULT 0`;
+ await db`ALTER TABLE nexql_sync.sync_accounts ADD COLUMN IF NOT EXISTS item_count INT NOT NULL DEFAULT 0`;
+ await db`ALTER TABLE nexql_sync.sync_accounts ADD COLUMN IF NOT EXISTS inactive_since TIMESTAMPTZ`;
+ await db`ALTER TABLE nexql_sync.sync_accounts ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT now()`;
await db`
- CREATE TABLE IF NOT EXISTS pgstudio_sync.sync_devices (
+ CREATE TABLE IF NOT EXISTS nexql_sync.sync_devices (
account_id TEXT NOT NULL,
device_id TEXT NOT NULL,
device_name TEXT,
@@ -109,7 +109,7 @@ async function ensureSchema() {
`;
await db`
CREATE INDEX IF NOT EXISTS sync_devices_account_idx
- ON pgstudio_sync.sync_devices (account_id, last_seen DESC)
+ ON nexql_sync.sync_devices (account_id, last_seen DESC)
`;
})();
}
@@ -131,8 +131,8 @@ async function spaceCursor(spaceId) {
const db = getSql();
const rows = await db`
SELECT GREATEST(
- COALESCE((SELECT MAX(version) FROM pgstudio_sync.items_v2 WHERE space_id = ${spaceId}), 0),
- COALESCE((SELECT MAX(version) FROM pgstudio_sync.deletes_v2 WHERE space_id = ${spaceId}), 0)
+ COALESCE((SELECT MAX(version) FROM nexql_sync.items_v2 WHERE space_id = ${spaceId}), 0),
+ COALESCE((SELECT MAX(version) FROM nexql_sync.deletes_v2 WHERE space_id = ${spaceId}), 0)
) AS cursor
`;
return Number(rows[0]?.cursor || 0);
@@ -148,13 +148,13 @@ async function pullDelta(spaceId, since) {
SELECT item_id, kind, content_hash, version, device_id,
encode(blob, 'base64') AS blob,
updated_at
- FROM pgstudio_sync.items_v2
+ FROM nexql_sync.items_v2
WHERE space_id = ${spaceId} AND version > ${sinceVersion}
ORDER BY version ASC
`;
const deleteRows = await db`
SELECT item_id, version
- FROM pgstudio_sync.deletes_v2
+ FROM nexql_sync.deletes_v2
WHERE space_id = ${spaceId} AND version > ${sinceVersion}
ORDER BY version ASC
`;
@@ -196,18 +196,18 @@ async function pushBatch(spaceId, deviceId, ops) {
if (op.op === 'delete') {
return db`
WITH existing AS (
- SELECT version FROM pgstudio_sync.items_v2
+ SELECT version FROM nexql_sync.items_v2
WHERE space_id = ${spaceId} AND item_id = ${op.item_id}
), del AS (
- DELETE FROM pgstudio_sync.items_v2
+ DELETE FROM nexql_sync.items_v2
WHERE space_id = ${spaceId} AND item_id = ${op.item_id} AND version <= ${baseVersion}
RETURNING item_id
), logged AS (
- INSERT INTO pgstudio_sync.deletes_v2 (space_id, item_id, version, deleted_by, deleted_at)
- SELECT ${spaceId}, ${op.item_id}, nextval('pgstudio_sync.cursor_seq'), ${device}, now()
+ INSERT INTO nexql_sync.deletes_v2 (space_id, item_id, version, deleted_by, deleted_at)
+ SELECT ${spaceId}, ${op.item_id}, nextval('nexql_sync.cursor_seq'), ${device}, now()
WHERE EXISTS (SELECT 1 FROM del) OR NOT EXISTS (SELECT 1 FROM existing)
ON CONFLICT (space_id, item_id) DO UPDATE
- SET version = nextval('pgstudio_sync.cursor_seq'), deleted_by = EXCLUDED.deleted_by, deleted_at = now()
+ SET version = nextval('nexql_sync.cursor_seq'), deleted_by = EXCLUDED.deleted_by, deleted_at = now()
RETURNING version
)
SELECT ${op.item_id} AS item_id,
@@ -219,19 +219,19 @@ async function pushBatch(spaceId, deviceId, ops) {
const blob = Buffer.from(String(op.blob || ''), 'base64');
return db`
WITH existing AS (
- SELECT version, content_hash FROM pgstudio_sync.items_v2
+ SELECT version, content_hash FROM nexql_sync.items_v2
WHERE space_id = ${spaceId} AND item_id = ${op.item_id}
), up AS (
- INSERT INTO pgstudio_sync.items_v2
+ INSERT INTO nexql_sync.items_v2
(space_id, item_id, kind, blob, content_hash, version, device_id, updated_at)
VALUES
(${spaceId}, ${op.item_id}, ${op.kind}, ${blob}, ${op.content_hash},
- nextval('pgstudio_sync.cursor_seq'), ${device}, now())
+ nextval('nexql_sync.cursor_seq'), ${device}, now())
ON CONFLICT (space_id, item_id) DO UPDATE
SET kind = EXCLUDED.kind, blob = EXCLUDED.blob, content_hash = EXCLUDED.content_hash,
- version = nextval('pgstudio_sync.cursor_seq'), device_id = EXCLUDED.device_id, updated_at = now()
- WHERE pgstudio_sync.items_v2.version <= ${baseVersion}
- OR pgstudio_sync.items_v2.content_hash = EXCLUDED.content_hash
+ version = nextval('nexql_sync.cursor_seq'), device_id = EXCLUDED.device_id, updated_at = now()
+ WHERE nexql_sync.items_v2.version <= ${baseVersion}
+ OR nexql_sync.items_v2.content_hash = EXCLUDED.content_hash
RETURNING version
)
SELECT ${op.item_id} AS item_id,
@@ -269,8 +269,8 @@ async function pushBatch(spaceId, deviceId, ops) {
async function resetSpace(spaceId) {
await ensureSchema();
const db = getSql();
- await db`DELETE FROM pgstudio_sync.items_v2 WHERE space_id = ${spaceId}`;
- await db`DELETE FROM pgstudio_sync.deletes_v2 WHERE space_id = ${spaceId}`;
+ await db`DELETE FROM nexql_sync.items_v2 WHERE space_id = ${spaceId}`;
+ await db`DELETE FROM nexql_sync.deletes_v2 WHERE space_id = ${spaceId}`;
await refreshAccountQuota(spaceId);
}
@@ -281,12 +281,12 @@ async function createSpace(spaceId, name, ownerEmail) {
const db = getSql();
const owner = normalizeEmail(ownerEmail);
await db`
- INSERT INTO pgstudio_sync.spaces (space_id, name, owner_email)
+ INSERT INTO nexql_sync.spaces (space_id, name, owner_email)
VALUES (${spaceId}, ${name}, ${owner})
ON CONFLICT (space_id) DO UPDATE SET name = EXCLUDED.name
`;
await db`
- INSERT INTO pgstudio_sync.space_members (space_id, email, role)
+ INSERT INTO nexql_sync.space_members (space_id, email, role)
VALUES (${spaceId}, ${owner}, 'owner')
ON CONFLICT (space_id, email) DO UPDATE SET role = 'owner'
`;
@@ -297,8 +297,8 @@ async function listSpacesForEmail(email) {
const db = getSql();
return db`
SELECT s.space_id, s.name, s.owner_email, m.role
- FROM pgstudio_sync.space_members m
- JOIN pgstudio_sync.spaces s ON s.space_id = m.space_id
+ FROM nexql_sync.space_members m
+ JOIN nexql_sync.spaces s ON s.space_id = m.space_id
WHERE m.email = ${normalizeEmail(email)}
ORDER BY s.created_at ASC
`;
@@ -308,7 +308,7 @@ async function listMembers(spaceId) {
await ensureSchema();
const db = getSql();
return db`
- SELECT email, role, added_at FROM pgstudio_sync.space_members
+ SELECT email, role, added_at FROM nexql_sync.space_members
WHERE space_id = ${spaceId} ORDER BY added_at ASC
`;
}
@@ -317,7 +317,7 @@ async function addMember(spaceId, email, role) {
await ensureSchema();
const db = getSql();
await db`
- INSERT INTO pgstudio_sync.space_members (space_id, email, role)
+ INSERT INTO nexql_sync.space_members (space_id, email, role)
VALUES (${spaceId}, ${normalizeEmail(email)}, ${role})
ON CONFLICT (space_id, email) DO UPDATE SET role = EXCLUDED.role
`;
@@ -327,7 +327,7 @@ async function removeMember(spaceId, email) {
await ensureSchema();
const db = getSql();
await db`
- DELETE FROM pgstudio_sync.space_members
+ DELETE FROM nexql_sync.space_members
WHERE space_id = ${spaceId} AND email = ${normalizeEmail(email)} AND role <> 'owner'
`;
}
@@ -342,7 +342,7 @@ async function memberRole(spaceId, email, accountId) {
await ensureSchema();
const db = getSql();
const rows = await db`
- SELECT role FROM pgstudio_sync.space_members
+ SELECT role FROM nexql_sync.space_members
WHERE space_id = ${spaceId} AND email = ${normalizeEmail(email)} LIMIT 1
`;
return rows.length ? rows[0].role : null;
@@ -373,12 +373,12 @@ async function refreshAccountQuota(accountId) {
const rows = await db`
SELECT COALESCE(SUM(octet_length(blob)), 0)::bigint AS bytes_used,
COUNT(*)::int AS item_count
- FROM pgstudio_sync.items_v2
+ FROM nexql_sync.items_v2
WHERE space_id = ${accountId}
`;
const stats = rows[0] || { bytes_used: 0, item_count: 0 };
await db`
- INSERT INTO pgstudio_sync.sync_accounts (account_id, bytes_used, item_count, updated_at)
+ INSERT INTO nexql_sync.sync_accounts (account_id, bytes_used, item_count, updated_at)
VALUES (${accountId}, ${stats.bytes_used}, ${stats.item_count}, now())
ON CONFLICT (account_id) DO UPDATE SET
bytes_used = EXCLUDED.bytes_used, item_count = EXCLUDED.item_count, updated_at = now()
@@ -390,13 +390,13 @@ async function getAccountQuota(accountId) {
const db = getSql();
const rows = await db`
SELECT tier, bytes_used, item_count, updated_at
- FROM pgstudio_sync.sync_accounts WHERE account_id = ${accountId} LIMIT 1
+ FROM nexql_sync.sync_accounts WHERE account_id = ${accountId} LIMIT 1
`;
if (!rows.length) {
await refreshAccountQuota(accountId);
const again = await db`
SELECT tier, bytes_used, item_count, updated_at
- FROM pgstudio_sync.sync_accounts WHERE account_id = ${accountId} LIMIT 1
+ FROM nexql_sync.sync_accounts WHERE account_id = ${accountId} LIMIT 1
`;
return again[0] || { tier: 'sponsor', bytes_used: 0, item_count: 0, updated_at: new Date() };
}
@@ -407,7 +407,7 @@ async function setAccountTier(accountId, tier) {
await ensureSchema();
const db = getSql();
await db`
- INSERT INTO pgstudio_sync.sync_accounts (account_id, tier, updated_at)
+ INSERT INTO nexql_sync.sync_accounts (account_id, tier, updated_at)
VALUES (${accountId}, ${tier}, now())
ON CONFLICT (account_id) DO UPDATE SET tier = EXCLUDED.tier, updated_at = now()
`;
@@ -420,12 +420,12 @@ async function upsertDevice(accountId, deviceId, deviceName) {
await ensureSchema();
const db = getSql();
await db`
- INSERT INTO pgstudio_sync.sync_devices (account_id, device_id, device_name, last_seen)
+ INSERT INTO nexql_sync.sync_devices (account_id, device_id, device_name, last_seen)
VALUES (${accountId}, ${deviceId}, ${deviceName || null}, now())
ON CONFLICT (account_id, device_id) DO UPDATE SET
device_name = CASE
WHEN EXCLUDED.device_name IS NOT NULL THEN EXCLUDED.device_name
- ELSE pgstudio_sync.sync_devices.device_name
+ ELSE nexql_sync.sync_devices.device_name
END,
last_seen = now()
`;
@@ -447,7 +447,7 @@ async function listDevices(accountId) {
await ensureSchema();
const db = getSql();
return db`
- SELECT device_id, device_name, last_seen FROM pgstudio_sync.sync_devices
+ SELECT device_id, device_name, last_seen FROM nexql_sync.sync_devices
WHERE account_id = ${accountId} ORDER BY last_seen DESC
`;
}
@@ -456,7 +456,7 @@ async function revokeDevice(accountId, deviceId) {
await ensureSchema();
const db = getSql();
const rows = await db`
- DELETE FROM pgstudio_sync.sync_devices
+ DELETE FROM nexql_sync.sync_devices
WHERE account_id = ${accountId} AND device_id = ${deviceId} RETURNING device_id
`;
return rows.length > 0;
@@ -469,10 +469,10 @@ async function markAccountInactive(accountId) {
await ensureSchema();
const db = getSql();
await db`
- INSERT INTO pgstudio_sync.sync_accounts (account_id, inactive_since, updated_at)
+ INSERT INTO nexql_sync.sync_accounts (account_id, inactive_since, updated_at)
VALUES (${accountId}, now(), now())
ON CONFLICT (account_id) DO UPDATE SET
- inactive_since = COALESCE(pgstudio_sync.sync_accounts.inactive_since, now()), updated_at = now()
+ inactive_since = COALESCE(nexql_sync.sync_accounts.inactive_since, now()), updated_at = now()
`;
}
@@ -483,7 +483,7 @@ async function markAccountActive(accountId) {
await ensureSchema();
const db = getSql();
await db`
- UPDATE pgstudio_sync.sync_accounts SET inactive_since = NULL, updated_at = now()
+ UPDATE nexql_sync.sync_accounts SET inactive_since = NULL, updated_at = now()
WHERE account_id = ${accountId}
`;
}
@@ -491,14 +491,14 @@ async function markAccountActive(accountId) {
async function deleteAccountCloudData(accountId, ownerEmail) {
await ensureSchema();
const db = getSql();
- await db`DELETE FROM pgstudio_sync.items_v2 WHERE space_id = ${accountId}`;
- await db`DELETE FROM pgstudio_sync.deletes_v2 WHERE space_id = ${accountId}`;
- await db`DELETE FROM pgstudio_sync.sync_devices WHERE account_id = ${accountId}`;
+ await db`DELETE FROM nexql_sync.items_v2 WHERE space_id = ${accountId}`;
+ await db`DELETE FROM nexql_sync.deletes_v2 WHERE space_id = ${accountId}`;
+ await db`DELETE FROM nexql_sync.sync_devices WHERE account_id = ${accountId}`;
if (ownerEmail) {
const email = normalizeEmail(ownerEmail);
- await db`DELETE FROM pgstudio_sync.spaces WHERE owner_email = ${email}`;
+ await db`DELETE FROM nexql_sync.spaces WHERE owner_email = ${email}`;
}
- await db`DELETE FROM pgstudio_sync.sync_accounts WHERE account_id = ${accountId}`;
+ await db`DELETE FROM nexql_sync.sync_accounts WHERE account_id = ${accountId}`;
}
/** Remove cloud blobs for accounts inactive longer than {@link CLOUD_INACTIVE_RETENTION_DAYS}. */
@@ -506,7 +506,7 @@ async function purgeInactiveCloudData() {
await ensureSchema();
const db = getSql();
const rows = await db`
- SELECT account_id FROM pgstudio_sync.sync_accounts
+ SELECT account_id FROM nexql_sync.sync_accounts
WHERE inactive_since IS NOT NULL
AND inactive_since < now() - (${CLOUD_INACTIVE_RETENTION_DAYS} * interval '1 day')
`;
diff --git a/docs/CLOUD_SYNC.md b/docs/CLOUD_SYNC.md
index 9073ede..d7dee80 100644
--- a/docs/CLOUD_SYNC.md
+++ b/docs/CLOUD_SYNC.md
@@ -82,7 +82,7 @@ Or use the walkthrough: **Set up NexQL Sync** (from the Welcome / Getting Starte
| Backend | Plan | Best for |
|---------|------|----------|
-| **Shared Postgres** | Free+ | Your own DB; `pgstudio_sync` schema |
+| **Shared Postgres** | Free+ | Your own DB; `nexql_sync` schema |
| **GitHub Gist** | Sponsor+ | Quick start; private gist; works in most editors |
| **OneDrive** | Sponsor+ | Microsoft 365 users; files in app folder |
| **Google Drive** | Sponsor+ | Google accounts; `drive.appdata` hidden folder |
@@ -129,7 +129,7 @@ Configure in **Settings → PostgreSQL Explorer → Sync**:
|---------|---------|
| `postgresExplorer.sync.auto` | Automatic debounced push and periodic pull (default: on) |
| `postgresExplorer.sync.pullIntervalMinutes` | How often to pull remote changes (default: 5) |
-| `postgresExplorer.sync.notebookFolder` | Local folder for synced `.pgsql` notebooks (default: `~/PgStudioNotebooks`) |
+| `postgresExplorer.sync.notebookFolder` | Local folder for synced `.pgsql` notebooks (default: `~/NexQLNotebooks`) |
| `postgresExplorer.sync.postgresConnectionId` | Connection ID for Shared Postgres backend |
| `postgresExplorer.sync.apiEndpoint` | NexQL Cloud API base URL |
| `postgresExplorer.sync.githubClientId` | GitHub OAuth app (device-flow fallback) |
diff --git a/docs/IDEA-------CHECKITOUT b/docs/IDEA-------CHECKITOUT
index 5e6103d..958323b 100644
--- a/docs/IDEA-------CHECKITOUT
+++ b/docs/IDEA-------CHECKITOUT
@@ -1 +1 @@
-Sentinel auto-switch — not a theme, a PgStudio feature: workbench.colorTheme swap suggestion when connecting to a PROD-tagged database. This is the single highest-value item on this list because it converts the theme family from a side artifact into a product feature no competitor has.
\ No newline at end of file
+Sentinel auto-switch — not a theme, a NexQL feature: workbench.colorTheme swap suggestion when connecting to a PROD-tagged database. This is the single highest-value item on this list because it converts the theme family from a side artifact into a product feature no competitor has.
\ No newline at end of file
diff --git a/docs/NEON_DATABASE_SCHEMA.md b/docs/NEON_DATABASE_SCHEMA.md
index 30ffbdb..7f1ec60 100644
--- a/docs/NEON_DATABASE_SCHEMA.md
+++ b/docs/NEON_DATABASE_SCHEMA.md
@@ -1,10 +1,10 @@
# Neon Database Reference & Cheatsheet
-This document serves as the comprehensive reference and cheatsheet for all tables created and actively used on the Neon PostgreSQL database by the PgStudio (NexQL) backend.
+This document serves as the comprehensive reference and cheatsheet for all tables created and actively used on the Neon PostgreSQL database by the NexQL (NexQL) backend.
The database is divided into two primary schemas:
-1. **`pgstudio_license`**: Manages user licenses, device bindings, transaction events, and Razorpay webhook idempotency.
-2. **`pgstudio_sync`**: Powers the NexQL Cloud Sync v2 service using an optimized, git-like, end-to-end encrypted delta synchronization mechanism.
+1. **`nexql_license`**: Manages user licenses, device bindings, transaction events, and Razorpay webhook idempotency.
+2. **`nexql_sync`**: Powers the NexQL Cloud Sync v2 service using an optimized, git-like, end-to-end encrypted delta synchronization mechanism.
---
@@ -14,8 +14,8 @@ The following Mermaid diagram outlines the entity-relationship model and schema
```mermaid
erDiagram
- %% Schema: pgstudio_license
- subgraph pgstudio_license ["Schema: pgstudio_license (Licensing)"]
+ %% Schema: nexql_license
+ subgraph nexql_license ["Schema: nexql_license (Licensing)"]
licenses {
text license_key PK
text tier "sponsor | singularity"
@@ -50,8 +50,8 @@ erDiagram
}
end
- %% Schema: pgstudio_sync
- subgraph pgstudio_sync ["Schema: pgstudio_sync (NexQL Cloud Sync)"]
+ %% Schema: nexql_sync
+ subgraph nexql_sync ["Schema: nexql_sync (NexQL Cloud Sync)"]
sync_accounts {
text account_id PK "maps to license_key or github_id"
text tier "sponsor | singularity"
@@ -113,20 +113,20 @@ erDiagram
| Schema / Table | Status | Read / Write Intensity | Primary Purpose | Why it is Used & What relies on it |
| :--- | :--- | :--- | :--- | :--- |
-| **`pgstudio_license.licenses`** | **Active** | High / Medium | Entitlement State | Tracks subscription tiers, expiration dates, and validation status. Relied upon by client licensing API requests. |
-| **`pgstudio_license.devices`** | **Active** | High / High | Device Validation | Prevents users from exceeding activation limits (4 devices per tier). Excess devices pruned on validate. |
-| **`pgstudio_license.license_events`** | **Active** | Low / Medium | Audit Trail | Log of license changes (issuance, device bindings, subscription status modifications). |
-| **`pgstudio_license.webhook_events`** | **Active** | Medium / Low | Idempotency | Ensures Razorpay webhooks are processed exactly once. |
-| **`pgstudio_sync.sync_accounts`** | **Active** | High / Medium | Quota & Storage Tracking | Stores tenant usage limits (bytes used, item count, tier) and triggers cloud pruning if inactive. |
-| **`pgstudio_sync.sync_devices`** | **Active** | Medium / Medium | Sync Device Registry | Tracks active sync client devices for each user account. |
-| **`pgstudio_sync.spaces`** | **Active** | Medium / Low | Shared Workspace Registry | Models collaboration units (e.g. shared folders/teams). Personal folders are implicit. |
-| **`pgstudio_sync.space_members`** | **Active** | High / Low | ACL / Role Mapping | Authorizes pull/push actions for workspaces using Roles (`owner`, `editor`, `viewer`). |
-| **`pgstudio_sync.items_v2`** | **Active** | High / High | Encrypted Sync Storage | Holds AES-256-GCM encrypted client configurations, queries, and notebook blobs. |
-| **`pgstudio_sync.deletes_v2`** | **Active** | High / Medium | Delete Logs (Tombstones) | Git-like tombstones to prevent deleted items from resurrecting on client pulls. |
+| **`nexql_license.licenses`** | **Active** | High / Medium | Entitlement State | Tracks subscription tiers, expiration dates, and validation status. Relied upon by client licensing API requests. |
+| **`nexql_license.devices`** | **Active** | High / High | Device Validation | Prevents users from exceeding activation limits (4 devices per tier). Excess devices pruned on validate. |
+| **`nexql_license.license_events`** | **Active** | Low / Medium | Audit Trail | Log of license changes (issuance, device bindings, subscription status modifications). |
+| **`nexql_license.webhook_events`** | **Active** | Medium / Low | Idempotency | Ensures Razorpay webhooks are processed exactly once. |
+| **`nexql_sync.sync_accounts`** | **Active** | High / Medium | Quota & Storage Tracking | Stores tenant usage limits (bytes used, item count, tier) and triggers cloud pruning if inactive. |
+| **`nexql_sync.sync_devices`** | **Active** | Medium / Medium | Sync Device Registry | Tracks active sync client devices for each user account. |
+| **`nexql_sync.spaces`** | **Active** | Medium / Low | Shared Workspace Registry | Models collaboration units (e.g. shared folders/teams). Personal folders are implicit. |
+| **`nexql_sync.space_members`** | **Active** | High / Low | ACL / Role Mapping | Authorizes pull/push actions for workspaces using Roles (`owner`, `editor`, `viewer`). |
+| **`nexql_sync.items_v2`** | **Active** | High / High | Encrypted Sync Storage | Holds AES-256-GCM encrypted client configurations, queries, and notebook blobs. |
+| **`nexql_sync.deletes_v2`** | **Active** | High / Medium | Delete Logs (Tombstones) | Git-like tombstones to prevent deleted items from resurrecting on client pulls. |
---
-## 🔧 Schema `pgstudio_license` (Detailed Definition)
+## 🔧 Schema `nexql_license` (Detailed Definition)
This schema controls user licenses and limits device activations.
@@ -135,7 +135,7 @@ Stores valid license keys, emails, tiers, subscription periods, status, and expi
* **DDL Definition**:
```sql
- CREATE TABLE IF NOT EXISTS pgstudio_license.licenses (
+ CREATE TABLE IF NOT EXISTS nexql_license.licenses (
license_key TEXT PRIMARY KEY,
tier TEXT NOT NULL CHECK (tier IN ('sponsor','singularity')),
period TEXT NOT NULL DEFAULT 'monthly',
@@ -160,8 +160,8 @@ Tracks active client machines bound to each license key.
* **DDL Definition**:
```sql
- CREATE TABLE IF NOT EXISTS pgstudio_license.devices (
- license_key TEXT NOT NULL REFERENCES pgstudio_license.licenses(license_key),
+ CREATE TABLE IF NOT EXISTS nexql_license.devices (
+ license_key TEXT NOT NULL REFERENCES nexql_license.licenses(license_key),
instance_id TEXT NOT NULL,
device_name TEXT,
first_seen TIMESTAMPTZ NOT NULL DEFAULT now(),
@@ -180,7 +180,7 @@ Stores an append-only JSON audit log of operations associated with a license.
* **DDL Definition**:
```sql
- CREATE TABLE IF NOT EXISTS pgstudio_license.license_events (
+ CREATE TABLE IF NOT EXISTS nexql_license.license_events (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
license_key TEXT NOT NULL,
event_type TEXT NOT NULL,
@@ -199,7 +199,7 @@ Protects subscription webhook handlers against network retransmissions and doubl
* **DDL Definition**:
```sql
- CREATE TABLE IF NOT EXISTS pgstudio_license.webhook_events (
+ CREATE TABLE IF NOT EXISTS nexql_license.webhook_events (
razorpay_event_id TEXT PRIMARY KEY,
received_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
@@ -209,7 +209,7 @@ Protects subscription webhook handlers against network retransmissions and doubl
---
-## 📡 Schema `pgstudio_sync` (Detailed Definition)
+## 📡 Schema `nexql_sync` (Detailed Definition)
Powers the git-like, multi-device cloud synchronization feature.
@@ -218,7 +218,7 @@ Stores the active state of sync items (connections, queries, and SQL notebooks).
* **DDL Definition**:
```sql
- CREATE TABLE IF NOT EXISTS pgstudio_sync.items_v2 (
+ CREATE TABLE IF NOT EXISTS nexql_sync.items_v2 (
space_id TEXT NOT NULL,
item_id TEXT NOT NULL,
kind TEXT NOT NULL CHECK (kind IN ('connection','query','notebook')),
@@ -231,7 +231,7 @@ Stores the active state of sync items (connections, queries, and SQL notebooks).
);
```
* **Indexes & Sequences**:
- * Sequence: `pgstudio_sync.cursor_seq` used to supply monotonic version sequences.
+ * Sequence: `nexql_sync.cursor_seq` used to supply monotonic version sequences.
* Index: `items_v2_cursor_idx` ON `(space_id, version)` used to accelerate delta pulls.
* **Why & What**:
* Contains the encrypted sync payloads (encrypted client-side using AES-256-GCM).
@@ -242,7 +242,7 @@ Tombstone ledger tracking deleted items in a space.
* **DDL Definition**:
```sql
- CREATE TABLE IF NOT EXISTS pgstudio_sync.deletes_v2 (
+ CREATE TABLE IF NOT EXISTS nexql_sync.deletes_v2 (
space_id TEXT NOT NULL,
item_id TEXT NOT NULL,
version BIGINT NOT NULL,
@@ -261,15 +261,15 @@ Models shared team spaces and role permissions. Personal spaces are represented
* **DDL Definitions**:
```sql
- CREATE TABLE IF NOT EXISTS pgstudio_sync.spaces (
+ CREATE TABLE IF NOT EXISTS nexql_sync.spaces (
space_id TEXT PRIMARY KEY,
name TEXT NOT NULL,
owner_email TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
- CREATE TABLE IF NOT EXISTS pgstudio_sync.space_members (
- space_id TEXT NOT NULL REFERENCES pgstudio_sync.spaces(space_id) ON DELETE CASCADE,
+ CREATE TABLE IF NOT EXISTS nexql_sync.space_members (
+ space_id TEXT NOT NULL REFERENCES nexql_sync.spaces(space_id) ON DELETE CASCADE,
email TEXT NOT NULL,
role TEXT NOT NULL CHECK (role IN ('owner','editor','viewer')),
added_at TIMESTAMPTZ NOT NULL DEFAULT now(),
@@ -284,7 +284,7 @@ Tracks quota limits, active sync client configurations, and handles retention pa
* **DDL Definitions**:
```sql
- CREATE TABLE IF NOT EXISTS pgstudio_sync.sync_accounts (
+ CREATE TABLE IF NOT EXISTS nexql_sync.sync_accounts (
account_id TEXT PRIMARY KEY,
tier TEXT NOT NULL DEFAULT 'sponsor',
bytes_used BIGINT NOT NULL DEFAULT 0,
@@ -293,7 +293,7 @@ Tracks quota limits, active sync client configurations, and handles retention pa
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
- CREATE TABLE IF NOT EXISTS pgstudio_sync.sync_devices (
+ CREATE TABLE IF NOT EXISTS nexql_sync.sync_devices (
account_id TEXT NOT NULL,
device_id TEXT NOT NULL,
device_name TEXT,
@@ -314,7 +314,7 @@ Tracks quota limits, active sync client configurations, and handles retention pa
### 1. Subscription Expiration Cron
Runs periodically (via `expirePastDueLicenses()`) to flag licenses whose expiration timestamp has passed as `'expired'`.
```sql
-UPDATE pgstudio_license.licenses
+UPDATE nexql_license.licenses
SET status = 'expired', updated_at = now()
WHERE status = 'active'
AND expires_at IS NOT NULL
@@ -329,7 +329,7 @@ To optimize Neon DB storage usage, a routine runs (`purgeInactiveCloudData()`) t
2. Permanently deletes blobs and account entries from `items_v2`, `deletes_v2`, `sync_devices`, `spaces`, and `sync_accounts`.
### 3. Backfill One-Off Script
-A CLI script `scripts/backfill-license-kv-to-neon.js` allows migrating license entitlements from legacy KV databases (or local dev files) into `pgstudio_license.licenses` inside the Neon DB.
+A CLI script `scripts/backfill-license-kv-to-neon.js` allows migrating license entitlements from legacy KV databases (or local dev files) into `nexql_license.licenses` inside the Neon DB.
---
@@ -351,8 +351,8 @@ SELECT
COALESCE(sa.item_count, 0) AS sync_item_count,
sa.inactive_since AS sync_inactive_since,
l.created_at AS user_created_at
-FROM pgstudio_license.licenses l
-LEFT JOIN pgstudio_sync.sync_accounts sa
+FROM nexql_license.licenses l
+LEFT JOIN nexql_sync.sync_accounts sa
ON l.license_key = sa.account_id OR lower(l.email) = lower(sa.account_id)
ORDER BY l.created_at DESC;
```
@@ -368,8 +368,8 @@ SELECT
COALESCE(d.device_name, 'Unnamed Device') AS device_name,
d.first_seen,
d.last_seen
-FROM pgstudio_license.licenses l
-JOIN pgstudio_license.devices d ON l.license_key = d.license_key
+FROM nexql_license.licenses l
+JOIN nexql_license.devices d ON l.license_key = d.license_key
WHERE d.revoked_at IS NULL
ORDER BY l.email, d.last_seen DESC;
```
@@ -383,8 +383,8 @@ SELECT
sd.device_id AS sync_device_id,
COALESCE(sd.device_name, 'Unnamed Device') AS sync_device_name,
sd.last_seen AS sync_device_last_seen
-FROM pgstudio_license.licenses l
-JOIN pgstudio_sync.sync_devices sd ON l.license_key = sd.account_id
+FROM nexql_license.licenses l
+JOIN nexql_sync.sync_devices sd ON l.license_key = sd.account_id
ORDER BY l.email, sd.last_seen DESC;
```
@@ -401,8 +401,8 @@ WITH combined_devices AS (
d.instance_id AS device_id,
d.device_name,
d.last_seen
- FROM pgstudio_license.licenses l
- JOIN pgstudio_license.devices d ON l.license_key = d.license_key
+ FROM nexql_license.licenses l
+ JOIN nexql_license.devices d ON l.license_key = d.license_key
WHERE d.revoked_at IS NULL
UNION ALL
@@ -415,8 +415,8 @@ WITH combined_devices AS (
sd.device_id AS device_id,
sd.device_name,
sd.last_seen
- FROM pgstudio_license.licenses l
- JOIN pgstudio_sync.sync_devices sd ON l.license_key = sd.account_id
+ FROM nexql_license.licenses l
+ JOIN nexql_sync.sync_devices sd ON l.license_key = sd.account_id
)
SELECT
user_email,
@@ -440,8 +440,8 @@ SELECT
sm.email AS member_email,
sm.role AS member_role,
sm.added_at
-FROM pgstudio_sync.spaces s
-JOIN pgstudio_sync.space_members sm ON s.space_id = sm.space_id
+FROM nexql_sync.spaces s
+JOIN nexql_sync.space_members sm ON s.space_id = sm.space_id
ORDER BY s.owner_email, s.name, sm.role DESC;
```
diff --git a/docs/RAZORPAY.md b/docs/RAZORPAY.md
index b36c80c..ff1b52c 100644
--- a/docs/RAZORPAY.md
+++ b/docs/RAZORPAY.md
@@ -286,7 +286,7 @@ Success: `{ "ok": true, "limit", "devices": [{ "instanceId" }] }`.
- **INR** if timezone is `Asia/Kolkata`, or `navigator.language` is `en-in` / `hi-in`
- **USD** otherwise
-User overrides are stored in `sessionStorage` (`pgstudio_pricing_currency`, `pgstudio_pricing_period`).
+User overrides are stored in `sessionStorage` (`nexql_pricing_currency`, `nexql_pricing_period`).
---
diff --git a/docs/RELEASE_NOTES_v2.0.0.md b/docs/RELEASE_NOTES_v2.0.0.md
index 2db355c..2a24e06 100644
--- a/docs/RELEASE_NOTES_v2.0.0.md
+++ b/docs/RELEASE_NOTES_v2.0.0.md
@@ -77,4 +77,4 @@ Simply let VS Code auto-update the extension, or run:
```bash
ext install ric-v.postgres-explorer
```
-If you encounter any issues, please submit them to our repository [GitHub Issues](https://github.com/dev-asterix/PgStudio/issues). Thank you for being a part of the NexQL community!
+If you encounter any issues, please submit them to our repository [GitHub Issues](https://github.com/dev-asterix/NexQL/issues). Thank you for being a part of the NexQL community!
diff --git a/docs/WEBSITE_CONTEXT.md b/docs/WEBSITE_CONTEXT.md
index c590e54..9b4c409 100644
--- a/docs/WEBSITE_CONTEXT.md
+++ b/docs/WEBSITE_CONTEXT.md
@@ -33,7 +33,7 @@ Theme JSON lives only in the **[NexQL-Themes](https://github.com/ric-v/NexQL-The
**Runtime module:** `docs/js/theme-loader.mjs`
- Fetches manifest + theme JSON → `parseThemeSummary()` → CSS custom properties on `:root`
-- Persists choice in `localStorage` key `pgstudio-docs-theme`
+- Persists choice in `localStorage` key `nexql-docs-theme`
- Default theme: `claudy-day`
- Fallback palette if CDN/proxy unavailable (Drift Dark–like tokens)
- Exposes `window.NexqlThemes` for workbench integration
diff --git a/docs/html/editor-file-views.html b/docs/html/editor-file-views.html
index a89c677..80865d9 100644
--- a/docs/html/editor-file-views.html
+++ b/docs/html/editor-file-views.html
@@ -247,7 +247,7 @@ Everything NexQL does for you
?
Which databases work with NexQL?
-
Any PostgreSQL-wire-compatible database. Verified: PostgreSQL 12–17, Neon, Supabase, TimescaleDB, YugabyteDB, AWS RDS / Aurora, Google Cloud SQL / AlloyDB, and Azure Database for PostgreSQL. See the platform compatibility guide for connection settings and caveats.
+
Any PostgreSQL-wire-compatible database. Verified: PostgreSQL 12–17, Neon, Supabase, TimescaleDB, YugabyteDB, AWS RDS / Aurora, Google Cloud SQL / AlloyDB, and Azure Database for PostgreSQL. See the platform compatibility guide for connection settings and caveats.
@@ -324,7 +324,7 @@ 🚀 Install and Start in 2 Minutes
diff --git a/docs/html/minimized-overview.html b/docs/html/minimized-overview.html
index 410af9f..beee611 100644
--- a/docs/html/minimized-overview.html
+++ b/docs/html/minimized-overview.html
@@ -468,25 +468,25 @@ Analyze
Works with any PostgreSQL-wire database
- Platform compatibility guide ↗
@@ -520,7 +520,7 @@ Good to know
Neon, Supabase, TimescaleDB (and Timescale Cloud),
YugabyteDB (YSQL), and managed Postgres on AWS RDS / Aurora, Google
Cloud SQL / AlloyDB, and Azure Database for PostgreSQL. CockroachDB is not
- supported today. See the platform compatibility guide for per-provider connection
settings and caveats.
@@ -638,16 +638,16 @@ Install in one click.