@elyracode/db-tools 0.3.1 → 0.3.2
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 +26 -5
- package/extensions/index.ts +75 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,20 +10,41 @@ elyra install npm:@elyracode/db-tools
|
|
|
10
10
|
|
|
11
11
|
## Configuration
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
### Automatic: .env file (recommended)
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
If your project has a `.env` file (e.g. Laravel), db-tools reads it automatically. Standard key names are mapped:
|
|
16
|
+
|
|
17
|
+
| .env key | Maps to | Used by |
|
|
18
|
+
|----------|---------|--------|
|
|
19
|
+
| `DB_HOST` | `ELYRA_MYSQL_HOST` | MySQL |
|
|
20
|
+
| `DB_PORT` | `ELYRA_MYSQL_PORT` | MySQL |
|
|
21
|
+
| `DB_DATABASE` | `ELYRA_MYSQL_DATABASE` | MySQL |
|
|
22
|
+
| `DB_USERNAME` | `ELYRA_MYSQL_USER` | MySQL |
|
|
23
|
+
| `DB_PASSWORD` | `ELYRA_MYSQL_PASSWORD` | MySQL |
|
|
24
|
+
| `CLICKHOUSE_HOST` | `ELYRA_CLICKHOUSE_HOST` | ClickHouse |
|
|
25
|
+
| `CLICKHOUSE_PORT` | `ELYRA_CLICKHOUSE_PORT` | ClickHouse |
|
|
26
|
+
| `CLICKHOUSE_DATABASE` | `ELYRA_CLICKHOUSE_DATABASE` | ClickHouse |
|
|
27
|
+
| `CLICKHOUSE_USERNAME` | `ELYRA_CLICKHOUSE_USERNAME` | ClickHouse |
|
|
28
|
+
| `CLICKHOUSE_PASSWORD` | `ELYRA_CLICKHOUSE_PASSWORD` | ClickHouse |
|
|
29
|
+
| `CLICKHOUSE_HTTPS` | `ELYRA_CLICKHOUSE_HTTPS` | ClickHouse |
|
|
30
|
+
| `CLICKHOUSE_TIMEOUT_CONNECT` | `ELYRA_CLICKHOUSE_TIMEOUT_CONNECT` | ClickHouse |
|
|
31
|
+
| `CLICKHOUSE_TIMEOUT_QUERY` | `ELYRA_CLICKHOUSE_TIMEOUT_QUERY` | ClickHouse |
|
|
32
|
+
|
|
33
|
+
For a typical Laravel project, your existing `.env` already has `DB_HOST`, `DB_DATABASE`, etc. -- db-tools picks them up with zero configuration.
|
|
34
|
+
|
|
35
|
+
### Manual: environment variables
|
|
36
|
+
|
|
37
|
+
You can also set `ELYRA_*` env vars directly. These always take precedence over `.env` values.
|
|
16
38
|
|
|
17
39
|
```
|
|
40
|
+
# MySQL
|
|
18
41
|
export ELYRA_MYSQL_HOST=localhost
|
|
19
42
|
export ELYRA_MYSQL_PORT=3306
|
|
20
43
|
export ELYRA_MYSQL_USER=readonly_user
|
|
21
44
|
export ELYRA_MYSQL_PASSWORD=secret
|
|
22
45
|
export ELYRA_MYSQL_DATABASE=myapp
|
|
23
|
-
```
|
|
24
46
|
|
|
25
|
-
|
|
26
|
-
```
|
|
47
|
+
# ClickHouse
|
|
27
48
|
export ELYRA_CLICKHOUSE_HOST=localhost
|
|
28
49
|
export ELYRA_CLICKHOUSE_PORT=8123
|
|
29
50
|
export ELYRA_CLICKHOUSE_DATABASE=mydb
|
package/extensions/index.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
1
3
|
import type { ExtensionAPI } from "@elyracode/coding-agent";
|
|
2
4
|
import { createClient } from "@clickhouse/client";
|
|
3
5
|
import mysql2 from "mysql2/promise";
|
|
4
6
|
import { Type } from "typebox";
|
|
5
7
|
|
|
6
8
|
export default function (elyra: ExtensionAPI) {
|
|
9
|
+
// ── Load .env ──
|
|
10
|
+
// Reads the project's .env file (if it exists) and maps common Laravel/Docker
|
|
11
|
+
// env var names to the ELYRA_ equivalents. Explicit ELYRA_* env vars always
|
|
12
|
+
// take precedence over .env values.
|
|
13
|
+
loadEnvFile(elyra);
|
|
14
|
+
|
|
7
15
|
// ── Configuration ──
|
|
8
|
-
// Connection
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// ELYRA_CLICKHOUSE_TIMEOUT_CONNECT, ELYRA_CLICKHOUSE_TIMEOUT_QUERY
|
|
16
|
+
// Connection config is resolved from (in priority order):
|
|
17
|
+
// 1. ELYRA_MYSQL_* / ELYRA_CLICKHOUSE_* environment variables
|
|
18
|
+
// 2. Standard names from .env: DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_DATABASE (MySQL)
|
|
19
|
+
// CLICKHOUSE_HOST, CLICKHOUSE_PORT, CLICKHOUSE_DATABASE, CLICKHOUSE_USERNAME, etc. (ClickHouse)
|
|
13
20
|
|
|
14
21
|
// ── Tool: query_mysql ──
|
|
15
22
|
elyra.registerTool({
|
|
@@ -266,6 +273,69 @@ function isReadOnly(sql: string): boolean {
|
|
|
266
273
|
return /^(SELECT|SHOW|DESCRIBE|DESC|EXPLAIN|WITH)\b/.test(trimmed);
|
|
267
274
|
}
|
|
268
275
|
|
|
276
|
+
// ── .env Loading ──
|
|
277
|
+
|
|
278
|
+
/** Parse a .env file into key-value pairs (handles quotes and comments) */
|
|
279
|
+
function parseEnvFile(content: string): Record<string, string> {
|
|
280
|
+
const result: Record<string, string> = {};
|
|
281
|
+
for (const line of content.split("\n")) {
|
|
282
|
+
const trimmed = line.trim();
|
|
283
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
284
|
+
const eqIndex = trimmed.indexOf("=");
|
|
285
|
+
if (eqIndex === -1) continue;
|
|
286
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
287
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
288
|
+
// Strip surrounding quotes
|
|
289
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
290
|
+
value = value.slice(1, -1);
|
|
291
|
+
}
|
|
292
|
+
result[key] = value;
|
|
293
|
+
}
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Mapping from standard .env keys (Laravel, Docker, etc.) to ELYRA_ env vars.
|
|
299
|
+
* Only sets the ELYRA_ var if it's not already set (explicit env vars win).
|
|
300
|
+
*/
|
|
301
|
+
const ENV_KEY_MAP: Array<[string, string]> = [
|
|
302
|
+
// MySQL (Laravel DB_* convention)
|
|
303
|
+
["DB_HOST", "ELYRA_MYSQL_HOST"],
|
|
304
|
+
["DB_PORT", "ELYRA_MYSQL_PORT"],
|
|
305
|
+
["DB_DATABASE", "ELYRA_MYSQL_DATABASE"],
|
|
306
|
+
["DB_USERNAME", "ELYRA_MYSQL_USER"],
|
|
307
|
+
["DB_PASSWORD", "ELYRA_MYSQL_PASSWORD"],
|
|
308
|
+
// ClickHouse
|
|
309
|
+
["CLICKHOUSE_HOST", "ELYRA_CLICKHOUSE_HOST"],
|
|
310
|
+
["CLICKHOUSE_PORT", "ELYRA_CLICKHOUSE_PORT"],
|
|
311
|
+
["CLICKHOUSE_DATABASE", "ELYRA_CLICKHOUSE_DATABASE"],
|
|
312
|
+
["CLICKHOUSE_USERNAME", "ELYRA_CLICKHOUSE_USERNAME"],
|
|
313
|
+
["CLICKHOUSE_PASSWORD", "ELYRA_CLICKHOUSE_PASSWORD"],
|
|
314
|
+
["CLICKHOUSE_HTTPS", "ELYRA_CLICKHOUSE_HTTPS"],
|
|
315
|
+
["CLICKHOUSE_TIMEOUT_CONNECT", "ELYRA_CLICKHOUSE_TIMEOUT_CONNECT"],
|
|
316
|
+
["CLICKHOUSE_TIMEOUT_QUERY", "ELYRA_CLICKHOUSE_TIMEOUT_QUERY"],
|
|
317
|
+
];
|
|
318
|
+
|
|
319
|
+
/** Load .env from the project root and map keys to ELYRA_ equivalents */
|
|
320
|
+
function loadEnvFile(elyra: ExtensionAPI): void {
|
|
321
|
+
try {
|
|
322
|
+
const cwd = process.cwd();
|
|
323
|
+
const envPath = join(cwd, ".env");
|
|
324
|
+
if (!existsSync(envPath)) return;
|
|
325
|
+
|
|
326
|
+
const parsed = parseEnvFile(readFileSync(envPath, "utf-8"));
|
|
327
|
+
|
|
328
|
+
for (const [sourceKey, targetKey] of ENV_KEY_MAP) {
|
|
329
|
+
const value = parsed[sourceKey];
|
|
330
|
+
if (value !== undefined && !process.env[targetKey]) {
|
|
331
|
+
process.env[targetKey] = value;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
} catch {
|
|
335
|
+
// Never fail on .env parse errors
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
269
339
|
// ── Schema Discovery ──
|
|
270
340
|
|
|
271
341
|
async function getMysqlSchema(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elyracode/db-tools",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Database tools for Elyra - query MySQL and ClickHouse with schema awareness and safety guardrails",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": ["elyra-package", "database", "mysql", "clickhouse", "sql"],
|