@kiyeonjeon21/datacontext 0.3.1 → 0.3.3

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/src/cli/index.ts CHANGED
@@ -34,9 +34,14 @@ function createAdapter(connectionString: string): DatabaseAdapter {
34
34
  return createPostgresAdapter(connectionString);
35
35
  } else if (url.startsWith('mysql://') || url.startsWith('mariadb://')) {
36
36
  return createMySQLAdapter(connectionString);
37
- } else if (url.startsWith('sqlite://') || url.endsWith('.sqlite') || url.endsWith('.sqlite3') || url.endsWith('.db') || url === ':memory:') {
38
- // SQLite: sqlite://path/to/db.sqlite or ./mydb.sqlite or :memory:
39
- const filePath = url.startsWith('sqlite://') ? url.replace('sqlite://', '') : connectionString;
37
+ } else if (url.startsWith('sqlite://') || url.startsWith('sqlite:') || url.endsWith('.sqlite') || url.endsWith('.sqlite3') || url.endsWith('.db') || url === ':memory:') {
38
+ // SQLite: sqlite://path or sqlite:path or ./mydb.sqlite or :memory:
39
+ let filePath = connectionString;
40
+ if (url.startsWith('sqlite://')) {
41
+ filePath = connectionString.replace(/^sqlite:\/\//i, '');
42
+ } else if (url.startsWith('sqlite:')) {
43
+ filePath = connectionString.replace(/^sqlite:/i, '');
44
+ }
40
45
  return createSQLiteAdapter(filePath);
41
46
  } else {
42
47
  throw new Error(
@@ -65,20 +70,37 @@ program
65
70
  .option('--allowed-tables <tables...>', 'Only allow access to these tables')
66
71
  .action(async (connectionString: string, options) => {
67
72
  try {
68
- // Parse connection string
69
- const config = parseConnectionString(connectionString);
70
-
71
73
  // Create adapter (auto-detect database type)
72
74
  const adapter = createAdapter(connectionString);
73
75
  await adapter.connect();
74
76
 
77
+ // Determine database ID for knowledge store
78
+ let databaseId: string;
79
+ const url = connectionString.toLowerCase();
80
+
81
+ if (url.startsWith('sqlite://') || url.startsWith('sqlite:') || url.endsWith('.sqlite') || url.endsWith('.sqlite3') || url.endsWith('.db') || url === ':memory:') {
82
+ // SQLite: use filename as database ID
83
+ let filePath = connectionString;
84
+ if (url.startsWith('sqlite://')) {
85
+ filePath = connectionString.replace(/^sqlite:\/\//i, '');
86
+ } else if (url.startsWith('sqlite:')) {
87
+ filePath = connectionString.replace(/^sqlite:/i, '');
88
+ }
89
+ const fileName = filePath.split('/').pop() || 'sqlite';
90
+ databaseId = `sqlite_${fileName.replace(/[^a-zA-Z0-9]/g, '_')}`;
91
+ } else {
92
+ // URL-based databases (postgres, mysql)
93
+ const config = parseConnectionString(connectionString);
94
+ databaseId = `${config.host}_${config.database}`;
95
+ }
96
+
75
97
  // Create knowledge store
76
- const databaseId = `${config.host}_${config.database}`;
77
98
  const knowledge = createKnowledgeStore(databaseId);
78
99
  await knowledge.load();
79
100
 
80
- // Update schema hash
81
- const schema = await adapter.getSchema(options.schema);
101
+ // Update schema hash (SQLite uses 'main' schema)
102
+ const schemaName = url.startsWith('sqlite') || url.endsWith('.db') ? 'main' : options.schema;
103
+ const schema = await adapter.getSchema(schemaName);
82
104
  knowledge.updateSchemaHash(schema.schemaHash);
83
105
  await knowledge.save();
84
106
 
@@ -836,21 +858,40 @@ program
836
858
  try {
837
859
  console.log('[datacontext] Starting REST API server...');
838
860
 
839
- // Parse connection string
840
- const config = parseConnectionString(connectionString);
841
-
842
861
  // Create adapter (auto-detect database type)
843
862
  const adapter = createAdapter(connectionString);
844
863
  await adapter.connect();
845
- console.log(`[datacontext] Connected to ${config.database}`);
864
+
865
+ // Determine database ID for knowledge store
866
+ let databaseId: string;
867
+ const url = connectionString.toLowerCase();
868
+
869
+ if (url.startsWith('sqlite://') || url.startsWith('sqlite:') || url.endsWith('.sqlite') || url.endsWith('.sqlite3') || url.endsWith('.db') || url === ':memory:') {
870
+ // SQLite: use filename as database ID
871
+ let filePath = connectionString;
872
+ if (url.startsWith('sqlite://')) {
873
+ filePath = connectionString.replace(/^sqlite:\/\//i, '');
874
+ } else if (url.startsWith('sqlite:')) {
875
+ filePath = connectionString.replace(/^sqlite:/i, '');
876
+ }
877
+ const fileName = filePath.split('/').pop() || 'sqlite';
878
+ databaseId = `sqlite_${fileName.replace(/[^a-zA-Z0-9]/g, '_')}`;
879
+ console.log(`[datacontext] Connected to SQLite: ${filePath}`);
880
+ } else {
881
+ // URL-based databases (postgres, mysql)
882
+ const config = parseConnectionString(connectionString);
883
+ databaseId = `${config.host}_${config.database}`;
884
+ console.log(`[datacontext] Connected to ${config.database}`);
885
+ }
846
886
 
847
887
  // Create knowledge store
848
- const databaseId = `${config.host}_${config.database}`;
849
888
  const knowledge = createKnowledgeStore(databaseId);
850
889
  await knowledge.load();
851
890
 
852
- // Update schema hash
853
- const schema = await adapter.getSchema(options.schema);
891
+ // Update schema hash (SQLite uses 'main' schema)
892
+ const isSqlite = url.startsWith('sqlite') || url.endsWith('.db') || url.endsWith('.sqlite') || url.endsWith('.sqlite3');
893
+ const schemaName = isSqlite ? 'main' : options.schema;
894
+ const schema = await adapter.getSchema(schemaName);
854
895
  knowledge.updateSchemaHash(schema.schemaHash);
855
896
  await knowledge.save();
856
897
 
@@ -48,7 +48,14 @@ export class KnowledgeStore {
48
48
  if (existsSync(this.dataPath)) {
49
49
  try {
50
50
  const content = await readFile(this.dataPath, 'utf-8');
51
- this.data = JSON.parse(content);
51
+ const parsed = JSON.parse(content) as KnowledgeData;
52
+
53
+ // Migration: ensure businessTerms array exists (for old data files)
54
+ if (!parsed.businessTerms) {
55
+ parsed.businessTerms = [];
56
+ }
57
+
58
+ this.data = parsed;
52
59
  } catch (error) {
53
60
  console.error(`Failed to load knowledge store: ${error}`);
54
61
  this.data = this.createEmptyData();
@@ -387,6 +394,11 @@ export class KnowledgeStore {
387
394
  throw new Error('Knowledge store not loaded');
388
395
  }
389
396
 
397
+ // Initialize businessTerms if not exists (migration for old data)
398
+ if (!this.data.businessTerms) {
399
+ this.data.businessTerms = [];
400
+ }
401
+
390
402
  // Check for duplicates
391
403
  const existing = this.data.businessTerms.find(
392
404
  t => t.term.toLowerCase() === term.toLowerCase()
package/test-sqlite.db ADDED
Binary file
@@ -1,29 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "datacontext": {
4
- "command": "node",
5
- "args": [
6
- "/Users/kiyeonjeon/Projects/business/DataContext-HQ/datacontext-cli/dist/cli/index.js",
7
- "connect",
8
- "sqlite:///Users/kiyeonjeon/Projects/business/DataContext-HQ/datacontext-cli/test-mcp.db"
9
- ],
10
- "env": {
11
- "ANTHROPIC_API_KEY": "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",
12
- "NODE_PATH": "/Users/kiyeonjeon/Projects/business/DataContext-HQ/datacontext-cli/node_modules"
13
- }
14
- }
15
- }
16
- }
17
-
18
-
19
- "datacontext": {
20
- "command": "node",
21
- "args": [
22
- "/Users/kiyeonjeon/Projects/business/DataContext-HQ/datacontext-cli/dist/cli/index.js",
23
- "connect",
24
- "postgres://postgres:postgres@localhost:5432/datacontext_test"
25
- ],
26
- "env": {
27
- "NODE_PATH": "/Users/kiyeonjeon/Projects/business/DataContext-HQ/datacontext-cli/node_modules"
28
- }
29
- }