spindb 0.38.1 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli/commands/backup.js +13 -2
- package/dist/cli/commands/backup.js.map +1 -1
- package/dist/cli/commands/clone.js +13 -1
- package/dist/cli/commands/clone.js.map +1 -1
- package/dist/cli/commands/connect.js +112 -40
- package/dist/cli/commands/connect.js.map +1 -1
- package/dist/cli/commands/delete.js +27 -0
- package/dist/cli/commands/delete.js.map +1 -1
- package/dist/cli/commands/engines.js +1 -1
- package/dist/cli/commands/engines.js.map +1 -1
- package/dist/cli/commands/export.js +12 -1
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/info.js +54 -12
- package/dist/cli/commands/info.js.map +1 -1
- package/dist/cli/commands/link.js +215 -0
- package/dist/cli/commands/link.js.map +1 -0
- package/dist/cli/commands/list.js +28 -7
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/logs.js +6 -0
- package/dist/cli/commands/logs.js.map +1 -1
- package/dist/cli/commands/menu/container-handlers.js +260 -32
- package/dist/cli/commands/menu/container-handlers.js.map +1 -1
- package/dist/cli/commands/menu/index.js +20 -4
- package/dist/cli/commands/menu/index.js.map +1 -1
- package/dist/cli/commands/menu/shell-handlers.js +206 -75
- package/dist/cli/commands/menu/shell-handlers.js.map +1 -1
- package/dist/cli/commands/query.js +35 -4
- package/dist/cli/commands/query.js.map +1 -1
- package/dist/cli/commands/restore.js +12 -1
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/run.js +6 -1
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/start.js +17 -2
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/stop.js +16 -1
- package/dist/cli/commands/stop.js.map +1 -1
- package/dist/cli/commands/url.js +59 -15
- package/dist/cli/commands/url.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/version.js +1 -1
- package/dist/core/container-manager.js +15 -1
- package/dist/core/container-manager.js.map +1 -1
- package/dist/core/remote-container.js +228 -0
- package/dist/core/remote-container.js.map +1 -0
- package/dist/engines/ferretdb/index.js +29 -10
- package/dist/engines/ferretdb/index.js.map +1 -1
- package/dist/engines/ferretdb/restore.js.map +1 -1
- package/dist/engines/mariadb/index.js +10 -2
- package/dist/engines/mariadb/index.js.map +1 -1
- package/dist/engines/mongodb/index.js +25 -3
- package/dist/engines/mongodb/index.js.map +1 -1
- package/dist/engines/mysql/index.js +10 -2
- package/dist/engines/mysql/index.js.map +1 -1
- package/dist/engines/postgresql/index.js +14 -2
- package/dist/engines/postgresql/index.js.map +1 -1
- package/dist/engines/redis/index.js +8 -1
- package/dist/engines/redis/index.js.map +1 -1
- package/dist/engines/valkey/index.js +8 -1
- package/dist/engines/valkey/index.js.map +1 -1
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +3 -2
|
@@ -14,6 +14,9 @@ import { configManager } from '../../../core/config-manager.js';
|
|
|
14
14
|
import { getPgwebStatus, stopPgweb, PGWEB_VERSION, } from '../../../core/pgweb-utils.js';
|
|
15
15
|
import { DBLAB_ENGINES, DBLAB_VERSION, getDblabArgs, getDblabPlatformSuffix, } from '../../../core/dblab-utils.js';
|
|
16
16
|
import { getEngine } from '../../../engines/index.js';
|
|
17
|
+
import { isRemoteContainer } from '../../../types/index.js';
|
|
18
|
+
import { loadCredentials } from '../../../core/credential-manager.js';
|
|
19
|
+
import { redactConnectionString, parseConnectionString, } from '../../../core/remote-container.js';
|
|
17
20
|
import { createSpinner } from '../../ui/spinner.js';
|
|
18
21
|
import { uiError, uiWarning, uiInfo, uiSuccess } from '../../ui/theme.js';
|
|
19
22
|
import { logDebug } from '../../../core/error-handler.js';
|
|
@@ -50,17 +53,28 @@ export async function handleCopyConnectionString(containerName, database) {
|
|
|
50
53
|
return;
|
|
51
54
|
}
|
|
52
55
|
const engine = getEngine(config.engine);
|
|
53
|
-
//
|
|
54
|
-
|
|
56
|
+
// Remote containers: use stored connection string (full from credentials)
|
|
57
|
+
let connectionString;
|
|
58
|
+
let displayString;
|
|
59
|
+
if (isRemoteContainer(config)) {
|
|
60
|
+
const creds = await loadCredentials(config.name, config.engine, 'remote');
|
|
61
|
+
connectionString =
|
|
62
|
+
creds?.connectionString ?? config.remote?.connectionString ?? '';
|
|
63
|
+
displayString = redactConnectionString(connectionString);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
connectionString = engine.getConnectionString(config, database);
|
|
67
|
+
displayString = connectionString;
|
|
68
|
+
}
|
|
55
69
|
const copied = await platformService.copyToClipboard(connectionString);
|
|
56
70
|
console.log();
|
|
57
71
|
if (copied) {
|
|
58
72
|
console.log(uiSuccess('Connection string copied to clipboard'));
|
|
59
|
-
console.log(chalk.gray(` ${
|
|
73
|
+
console.log(chalk.gray(` ${displayString}`));
|
|
60
74
|
}
|
|
61
75
|
else {
|
|
62
76
|
console.log(uiWarning('Could not copy to clipboard. Connection string:'));
|
|
63
|
-
console.log(chalk.cyan(` ${
|
|
77
|
+
console.log(chalk.cyan(` ${displayString}`));
|
|
64
78
|
}
|
|
65
79
|
console.log();
|
|
66
80
|
await escapeablePrompt([
|
|
@@ -78,9 +92,19 @@ export async function handleOpenShell(containerName, database) {
|
|
|
78
92
|
return;
|
|
79
93
|
}
|
|
80
94
|
const engine = getEngine(config.engine);
|
|
95
|
+
const isRemote = isRemoteContainer(config);
|
|
81
96
|
// Use provided database or fall back to container's default
|
|
82
97
|
const activeDatabase = database || config.database;
|
|
83
|
-
|
|
98
|
+
// For remote containers, use the stored remote connection string
|
|
99
|
+
let connectionString;
|
|
100
|
+
if (isRemote) {
|
|
101
|
+
const creds = await loadCredentials(config.name, config.engine, 'remote');
|
|
102
|
+
connectionString =
|
|
103
|
+
creds?.connectionString ?? config.remote?.connectionString ?? '';
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
connectionString = engine.getConnectionString(config, activeDatabase);
|
|
107
|
+
}
|
|
84
108
|
const shellCheckSpinner = createSpinner('Checking available shells...');
|
|
85
109
|
shellCheckSpinner.start();
|
|
86
110
|
const [usqlInstalled, pgcliInstalled, mycliInstalled, litecliInstalled, iredisInstalled,] = await Promise.all([
|
|
@@ -93,6 +117,16 @@ export async function handleOpenShell(containerName, database) {
|
|
|
93
117
|
shellCheckSpinner.stop();
|
|
94
118
|
// Clear the spinner line
|
|
95
119
|
process.stdout.write('\x1b[1A\x1b[2K');
|
|
120
|
+
// REST API engines (no CLI shell) can't be used remotely via console
|
|
121
|
+
if (isRemote &&
|
|
122
|
+
['qdrant', 'meilisearch', 'influxdb', 'weaviate', 'couchdb'].includes(config.engine)) {
|
|
123
|
+
console.log();
|
|
124
|
+
console.log(uiInfo('Console is not available for linked remote REST API databases.'));
|
|
125
|
+
console.log(chalk.gray(" Use your provider's web dashboard or API tools directly."));
|
|
126
|
+
console.log();
|
|
127
|
+
await pressEnterToContinue();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
96
130
|
// Engine-specific shell names
|
|
97
131
|
let defaultShellName;
|
|
98
132
|
let engineSpecificCli;
|
|
@@ -364,7 +398,8 @@ export async function handleOpenShell(containerName, database) {
|
|
|
364
398
|
}
|
|
365
399
|
}
|
|
366
400
|
// dblab visual TUI (supports PostgreSQL, MySQL, MariaDB, CockroachDB, SQLite, QuestDB)
|
|
367
|
-
|
|
401
|
+
// Not available for remote containers (hardcodes local connection)
|
|
402
|
+
if (DBLAB_ENGINES.has(config.engine) && !isRemote) {
|
|
368
403
|
const dblabPath = await configManager.getBinaryPath('dblab');
|
|
369
404
|
if (dblabPath) {
|
|
370
405
|
choices.push({
|
|
@@ -379,8 +414,8 @@ export async function handleOpenShell(containerName, database) {
|
|
|
379
414
|
});
|
|
380
415
|
}
|
|
381
416
|
}
|
|
382
|
-
// Web Panel section for engines with browser-based UIs
|
|
383
|
-
if (config.engine === 'clickhouse') {
|
|
417
|
+
// Web Panel section for engines with browser-based UIs (local only)
|
|
418
|
+
if (config.engine === 'clickhouse' && !isRemote) {
|
|
384
419
|
const httpPort = config.port + 1;
|
|
385
420
|
choices.push(new inquirer.Separator(chalk.gray(`───── Web Panel ─────`)));
|
|
386
421
|
choices.push({
|
|
@@ -388,7 +423,7 @@ export async function handleOpenShell(containerName, database) {
|
|
|
388
423
|
value: 'browser',
|
|
389
424
|
});
|
|
390
425
|
}
|
|
391
|
-
if (config.engine === 'questdb') {
|
|
426
|
+
if (config.engine === 'questdb' && !isRemote) {
|
|
392
427
|
const httpPort = config.port + 188;
|
|
393
428
|
choices.push(new inquirer.Separator(chalk.gray(`───── Web Panel ─────`)));
|
|
394
429
|
choices.push({
|
|
@@ -396,16 +431,17 @@ export async function handleOpenShell(containerName, database) {
|
|
|
396
431
|
value: 'browser',
|
|
397
432
|
});
|
|
398
433
|
}
|
|
399
|
-
if (config.engine === 'duckdb') {
|
|
434
|
+
if (config.engine === 'duckdb' && !isRemote) {
|
|
400
435
|
choices.push(new inquirer.Separator(chalk.gray(`───── Web Panel ─────`)));
|
|
401
436
|
choices.push({
|
|
402
437
|
name: `◎ Open Web UI (built-in, port 4213)`,
|
|
403
438
|
value: 'duckdb-ui',
|
|
404
439
|
});
|
|
405
440
|
}
|
|
406
|
-
if (
|
|
407
|
-
config.engine === '
|
|
408
|
-
|
|
441
|
+
if (!isRemote &&
|
|
442
|
+
(config.engine === 'postgresql' ||
|
|
443
|
+
config.engine === 'cockroachdb' ||
|
|
444
|
+
config.engine === 'ferretdb')) {
|
|
409
445
|
choices.push(new inquirer.Separator(chalk.gray(`───── Web Panel ─────`)));
|
|
410
446
|
const pgwebPath = await configManager.getBinaryPath('pgweb');
|
|
411
447
|
if (pgwebPath) {
|
|
@@ -1179,6 +1215,24 @@ async function launchPgweb(containerName, config, database) {
|
|
|
1179
1215
|
async function launchShell(containerName, config, connectionString, shellType, database) {
|
|
1180
1216
|
console.log(uiInfo(`Connecting to ${containerName}...`));
|
|
1181
1217
|
console.log();
|
|
1218
|
+
const isRemote = isRemoteContainer(config);
|
|
1219
|
+
// Parse remote connection string for host/port/user/password
|
|
1220
|
+
let rHost = '127.0.0.1';
|
|
1221
|
+
let rPort = config.port;
|
|
1222
|
+
let rUser = '';
|
|
1223
|
+
let rPass = '';
|
|
1224
|
+
if (isRemote) {
|
|
1225
|
+
try {
|
|
1226
|
+
const parsed = parseConnectionString(connectionString);
|
|
1227
|
+
rHost = parsed.host || config.remote?.host || '127.0.0.1';
|
|
1228
|
+
rPort = parsed.port || config.port;
|
|
1229
|
+
rUser = parsed.username || '';
|
|
1230
|
+
rPass = parsed.password || '';
|
|
1231
|
+
}
|
|
1232
|
+
catch {
|
|
1233
|
+
/* use defaults */
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1182
1236
|
let shellCmd;
|
|
1183
1237
|
let shellArgs;
|
|
1184
1238
|
let installHint;
|
|
@@ -1190,17 +1244,22 @@ async function launchShell(containerName, config, connectionString, shellType, d
|
|
|
1190
1244
|
installHint = 'brew install pgcli';
|
|
1191
1245
|
}
|
|
1192
1246
|
else if (shellType === 'mycli') {
|
|
1193
|
-
// mycli
|
|
1247
|
+
// mycli accepts connection strings directly
|
|
1194
1248
|
shellCmd = 'mycli';
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1249
|
+
if (isRemote) {
|
|
1250
|
+
shellArgs = [connectionString];
|
|
1251
|
+
}
|
|
1252
|
+
else {
|
|
1253
|
+
shellArgs = [
|
|
1254
|
+
'-h',
|
|
1255
|
+
'127.0.0.1',
|
|
1256
|
+
'-P',
|
|
1257
|
+
String(config.port),
|
|
1258
|
+
'-u',
|
|
1259
|
+
'root',
|
|
1260
|
+
database,
|
|
1261
|
+
];
|
|
1262
|
+
}
|
|
1204
1263
|
installHint = 'brew install mycli';
|
|
1205
1264
|
}
|
|
1206
1265
|
else if (shellType === 'litecli') {
|
|
@@ -1232,30 +1291,46 @@ async function launchShell(containerName, config, connectionString, shellType, d
|
|
|
1232
1291
|
// MySQL uses downloaded binaries - get the actual path
|
|
1233
1292
|
const mysqlPath = await configManager.getBinaryPath('mysql');
|
|
1234
1293
|
shellCmd = mysqlPath || 'mysql';
|
|
1235
|
-
|
|
1236
|
-
'-u',
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1294
|
+
if (isRemote) {
|
|
1295
|
+
shellArgs = ['-h', rHost, '-P', String(rPort), '-u', rUser || 'root'];
|
|
1296
|
+
if (rPass)
|
|
1297
|
+
shellArgs.push(`-p${rPass}`);
|
|
1298
|
+
shellArgs.push(database);
|
|
1299
|
+
}
|
|
1300
|
+
else {
|
|
1301
|
+
shellArgs = [
|
|
1302
|
+
'-u',
|
|
1303
|
+
'root',
|
|
1304
|
+
'-h',
|
|
1305
|
+
'127.0.0.1',
|
|
1306
|
+
'-P',
|
|
1307
|
+
String(config.port),
|
|
1308
|
+
database,
|
|
1309
|
+
];
|
|
1310
|
+
}
|
|
1244
1311
|
installHint = 'spindb engines download mysql';
|
|
1245
1312
|
}
|
|
1246
1313
|
else if (config.engine === 'mariadb') {
|
|
1247
1314
|
// MariaDB uses downloaded binaries, not system PATH - get the actual path
|
|
1248
1315
|
const mariadbPath = await configManager.getBinaryPath('mariadb');
|
|
1249
1316
|
shellCmd = mariadbPath || 'mariadb';
|
|
1250
|
-
|
|
1251
|
-
'-u',
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1317
|
+
if (isRemote) {
|
|
1318
|
+
shellArgs = ['-h', rHost, '-P', String(rPort), '-u', rUser || 'root'];
|
|
1319
|
+
if (rPass)
|
|
1320
|
+
shellArgs.push(`-p${rPass}`);
|
|
1321
|
+
shellArgs.push(database);
|
|
1322
|
+
}
|
|
1323
|
+
else {
|
|
1324
|
+
shellArgs = [
|
|
1325
|
+
'-u',
|
|
1326
|
+
'root',
|
|
1327
|
+
'-h',
|
|
1328
|
+
'127.0.0.1',
|
|
1329
|
+
'-P',
|
|
1330
|
+
String(config.port),
|
|
1331
|
+
database,
|
|
1332
|
+
];
|
|
1333
|
+
}
|
|
1259
1334
|
installHint = 'spindb engines download mariadb';
|
|
1260
1335
|
}
|
|
1261
1336
|
else if (config.engine === 'mongodb' || config.engine === 'ferretdb') {
|
|
@@ -1266,20 +1341,47 @@ async function launchShell(containerName, config, connectionString, shellType, d
|
|
|
1266
1341
|
else if (shellType === 'iredis') {
|
|
1267
1342
|
// iredis: enhanced Redis CLI
|
|
1268
1343
|
shellCmd = 'iredis';
|
|
1269
|
-
|
|
1344
|
+
if (isRemote) {
|
|
1345
|
+
shellArgs = ['-h', rHost, '-p', String(rPort)];
|
|
1346
|
+
if (rPass)
|
|
1347
|
+
shellArgs.push('-a', rPass);
|
|
1348
|
+
if (database)
|
|
1349
|
+
shellArgs.push('-n', database);
|
|
1350
|
+
}
|
|
1351
|
+
else {
|
|
1352
|
+
shellArgs = ['-h', '127.0.0.1', '-p', String(config.port), '-n', database];
|
|
1353
|
+
}
|
|
1270
1354
|
installHint = 'brew install iredis';
|
|
1271
1355
|
}
|
|
1272
1356
|
else if (config.engine === 'redis') {
|
|
1273
1357
|
// Default Redis shell
|
|
1274
1358
|
shellCmd = 'redis-cli';
|
|
1275
|
-
|
|
1359
|
+
if (isRemote) {
|
|
1360
|
+
shellArgs = ['-h', rHost, '-p', String(rPort)];
|
|
1361
|
+
if (rPass)
|
|
1362
|
+
shellArgs.push('-a', rPass);
|
|
1363
|
+
if (database)
|
|
1364
|
+
shellArgs.push('-n', database);
|
|
1365
|
+
}
|
|
1366
|
+
else {
|
|
1367
|
+
shellArgs = ['-h', '127.0.0.1', '-p', String(config.port), '-n', database];
|
|
1368
|
+
}
|
|
1276
1369
|
installHint = 'brew install redis';
|
|
1277
1370
|
}
|
|
1278
1371
|
else if (config.engine === 'valkey') {
|
|
1279
1372
|
// Default Valkey shell
|
|
1280
1373
|
const valkeyCliPath = await configManager.getBinaryPath('valkey-cli');
|
|
1281
1374
|
shellCmd = valkeyCliPath || 'valkey-cli';
|
|
1282
|
-
|
|
1375
|
+
if (isRemote) {
|
|
1376
|
+
shellArgs = ['-h', rHost, '-p', String(rPort)];
|
|
1377
|
+
if (rPass)
|
|
1378
|
+
shellArgs.push('-a', rPass);
|
|
1379
|
+
if (database)
|
|
1380
|
+
shellArgs.push('-n', database);
|
|
1381
|
+
}
|
|
1382
|
+
else {
|
|
1383
|
+
shellArgs = ['-h', '127.0.0.1', '-p', String(config.port), '-n', database];
|
|
1384
|
+
}
|
|
1283
1385
|
installHint = 'spindb engines download valkey';
|
|
1284
1386
|
}
|
|
1285
1387
|
else if (config.engine === 'clickhouse') {
|
|
@@ -1289,12 +1391,16 @@ async function launchShell(containerName, config, connectionString, shellType, d
|
|
|
1289
1391
|
shellArgs = [
|
|
1290
1392
|
'client',
|
|
1291
1393
|
'--host',
|
|
1292
|
-
'127.0.0.1',
|
|
1394
|
+
isRemote ? rHost : '127.0.0.1',
|
|
1293
1395
|
'--port',
|
|
1294
|
-
String(config.port),
|
|
1396
|
+
String(isRemote ? rPort : config.port),
|
|
1295
1397
|
'--database',
|
|
1296
1398
|
database,
|
|
1297
1399
|
];
|
|
1400
|
+
if (isRemote && rUser)
|
|
1401
|
+
shellArgs.push('--user', rUser);
|
|
1402
|
+
if (isRemote && rPass)
|
|
1403
|
+
shellArgs.push('--password', rPass);
|
|
1298
1404
|
installHint = 'spindb engines download clickhouse';
|
|
1299
1405
|
}
|
|
1300
1406
|
else if (config.engine === 'qdrant') {
|
|
@@ -1447,19 +1553,36 @@ async function launchShell(containerName, config, connectionString, shellType, d
|
|
|
1447
1553
|
.catch(() => 'surreal');
|
|
1448
1554
|
const namespace = config.name.replace(/-/g, '_');
|
|
1449
1555
|
shellCmd = surrealPath;
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1556
|
+
if (isRemote) {
|
|
1557
|
+
shellArgs = [
|
|
1558
|
+
'sql',
|
|
1559
|
+
'--endpoint',
|
|
1560
|
+
`ws://${rHost}:${rPort}`,
|
|
1561
|
+
'--namespace',
|
|
1562
|
+
namespace,
|
|
1563
|
+
'--database',
|
|
1564
|
+
database || 'default',
|
|
1565
|
+
];
|
|
1566
|
+
if (rUser)
|
|
1567
|
+
shellArgs.push('--username', rUser);
|
|
1568
|
+
if (rPass)
|
|
1569
|
+
shellArgs.push('--password', rPass);
|
|
1570
|
+
}
|
|
1571
|
+
else {
|
|
1572
|
+
shellArgs = [
|
|
1573
|
+
'sql',
|
|
1574
|
+
'--endpoint',
|
|
1575
|
+
`ws://127.0.0.1:${config.port}`,
|
|
1576
|
+
'--namespace',
|
|
1577
|
+
namespace,
|
|
1578
|
+
'--database',
|
|
1579
|
+
database || 'default',
|
|
1580
|
+
'--username',
|
|
1581
|
+
'root',
|
|
1582
|
+
'--password',
|
|
1583
|
+
'root',
|
|
1584
|
+
];
|
|
1585
|
+
}
|
|
1463
1586
|
installHint = 'spindb engines download surrealdb';
|
|
1464
1587
|
// SurrealDB writes history.txt to cwd - use container directory
|
|
1465
1588
|
spawnCwd = join(paths.containers, 'surrealdb', config.name);
|
|
@@ -1471,24 +1594,34 @@ async function launchShell(containerName, config, connectionString, shellType, d
|
|
|
1471
1594
|
.getCockroachPath(config.version)
|
|
1472
1595
|
.catch(() => 'cockroach');
|
|
1473
1596
|
shellCmd = cockroachPath;
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
'--
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1597
|
+
if (isRemote) {
|
|
1598
|
+
// Use --url for remote connections (supports full connection strings)
|
|
1599
|
+
shellArgs = ['sql', '--url', connectionString];
|
|
1600
|
+
}
|
|
1601
|
+
else {
|
|
1602
|
+
shellArgs = [
|
|
1603
|
+
'sql',
|
|
1604
|
+
'--insecure',
|
|
1605
|
+
'--host',
|
|
1606
|
+
`127.0.0.1:${config.port}`,
|
|
1607
|
+
'--database',
|
|
1608
|
+
database,
|
|
1609
|
+
];
|
|
1610
|
+
}
|
|
1482
1611
|
installHint = 'spindb engines download cockroachdb';
|
|
1483
1612
|
}
|
|
1484
1613
|
else if (config.engine === 'questdb') {
|
|
1485
1614
|
// QuestDB uses PostgreSQL wire protocol on port 8812
|
|
1486
|
-
// Default credentials: admin/quest
|
|
1487
1615
|
shellCmd = 'psql';
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1616
|
+
if (isRemote) {
|
|
1617
|
+
shellArgs = [connectionString];
|
|
1618
|
+
}
|
|
1619
|
+
else {
|
|
1620
|
+
// Default credentials: admin/quest
|
|
1621
|
+
const db = database || 'qdb';
|
|
1622
|
+
const questDbConnStr = `postgresql://admin:quest@127.0.0.1:${config.port}/${db}`;
|
|
1623
|
+
shellArgs = [questDbConnStr];
|
|
1624
|
+
}
|
|
1492
1625
|
installHint = 'brew install libpq && brew link --force libpq';
|
|
1493
1626
|
}
|
|
1494
1627
|
else if (config.engine === 'typedb') {
|
|
@@ -1510,8 +1643,6 @@ async function launchShell(containerName, config, connectionString, shellType, d
|
|
|
1510
1643
|
}
|
|
1511
1644
|
else if (config.engine === 'tigerbeetle') {
|
|
1512
1645
|
// TigerBeetle uses tigerbeetle repl command
|
|
1513
|
-
// Cluster ID 0 is the default for local single-node development.
|
|
1514
|
-
// TigerBeetle format/start also use cluster 0 (see engines/tigerbeetle/index.ts).
|
|
1515
1646
|
const clusterId = 0;
|
|
1516
1647
|
const engine = getEngine(config.engine);
|
|
1517
1648
|
const tigerbeetlePath = await engine
|
|
@@ -1521,7 +1652,7 @@ async function launchShell(containerName, config, connectionString, shellType, d
|
|
|
1521
1652
|
shellArgs = [
|
|
1522
1653
|
'repl',
|
|
1523
1654
|
`--cluster=${clusterId}`,
|
|
1524
|
-
`--addresses
|
|
1655
|
+
`--addresses=${isRemote ? rHost : '127.0.0.1'}:${isRemote ? rPort : config.port}`,
|
|
1525
1656
|
];
|
|
1526
1657
|
installHint = 'spindb engines download tigerbeetle';
|
|
1527
1658
|
}
|