Repository navigation
Expand file tree
/
Copy pathdb.js
More file actions
137 lines (122 loc) · 4.05 KB
/
Copy pathdb.js
File metadata and controls
137 lines (122 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const sqlite3 = require('sqlite3').verbose();
class Database {
constructor() {
this.db = null;
}
initialize() {
return new Promise((resolve, reject) => {
const dbPath = process.env.API_KEYS_DB_PATH || './apiKeys.db';
this.db = new sqlite3.Database(dbPath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, async (err) => {
if (err) {
console.error('Error connecting to the database:', err.message);
reject(err);
} else {
console.log('Connected to the apiKeys.db database.');
await this.run('PRAGMA journal_mode=WAL');
await this.run('PRAGMA synchronous=NORMAL');
this.createTables().then(resolve).catch(reject);
}
});
});
}
async createTables() {
await this.run(`CREATE TABLE IF NOT EXISTS apiKeys (
key TEXT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_used TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
tokens INTEGER DEFAULT 10,
rate_limit INTEGER DEFAULT 10,
active INTEGER DEFAULT 1,
description TEXT
)`);
await this.run(`CREATE TABLE IF NOT EXISTS apiUsage (
key TEXT,
model TEXT,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)`);
await this.run('CREATE INDEX IF NOT EXISTS idx_apiUsage_key ON apiUsage(key)');
await this.run(`CREATE TABLE IF NOT EXISTS webhooks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
url TEXT NOT NULL,
api_key TEXT,
last_triggered TIMESTAMP,
FOREIGN KEY (api_key) REFERENCES apiKeys(key)
)`);
await this.ensureColumns();
}
async ensureColumns() {
const rows = await this.all("PRAGMA table_info(apiKeys)");
const columns = rows.map(row => row.name);
if (!columns.includes('active')) {
await this.run("ALTER TABLE apiKeys ADD COLUMN active INTEGER DEFAULT 1");
console.log("Added 'active' column to 'apiKeys' table.");
}
if (!columns.includes('description')) {
await this.run("ALTER TABLE apiKeys ADD COLUMN description TEXT");
console.log("Added 'description' column to 'apiKeys' table.");
}
const usageRows = await this.all("PRAGMA table_info(apiUsage)");
const usageCols = usageRows.map(r => r.name);
if (!usageCols.includes('model')) {
await this.run("ALTER TABLE apiUsage ADD COLUMN model TEXT");
console.log("Added 'model' column to 'apiUsage' table.");
}
const webhookRows = await this.all("PRAGMA table_info(webhooks)");
const webhookCols = webhookRows.map(r => r.name);
if (!webhookCols.includes('api_key')) {
await this.run("ALTER TABLE webhooks ADD COLUMN api_key TEXT");
console.log("Added 'api_key' column to 'webhooks' table.");
}
if (!webhookCols.includes('last_triggered')) {
await this.run("ALTER TABLE webhooks ADD COLUMN last_triggered TIMESTAMP");
console.log("Added 'last_triggered' column to 'webhooks' table.");
}
}
get(sql, params = []) {
return new Promise((resolve, reject) => {
this.db.get(sql, params, (err, row) => {
if (err) reject(err);
else resolve(row);
});
});
}
run(sql, params = []) {
return new Promise((resolve, reject) => {
this.db.run(sql, params, function (err) {
if (err) reject(err);
else resolve(this);
});
});
}
all(sql, params = []) {
return new Promise((resolve, reject) => {
this.db.all(sql, params, (err, rows) => {
if (err) reject(err);
else resolve(rows);
});
});
}
close() {
return new Promise((resolve, reject) => {
if (!this.db) {
resolve();
return;
}
this.db.close((err) => {
this.db = null;
if (err) {
if (err.message === 'SQLITE_MISUSE: Database is closed') {
resolve();
} else {
console.error('Error closing the database connection:', err.message);
reject(err);
}
} else {
console.log('Closed the database connection.');
resolve();
}
});
});
}
}
module.exports = new Database();