admindb 1.0.1
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/LICENSE +21 -0
- package/README.md +325 -0
- package/dist/app.d.ts +36 -0
- package/dist/app.js +186 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +61 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +23 -0
- package/dist/config.js.map +1 -0
- package/dist/csv.d.ts +15 -0
- package/dist/csv.js +80 -0
- package/dist/csv.js.map +1 -0
- package/dist/db/database.d.ts +225 -0
- package/dist/db/database.js +497 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/export.d.ts +12 -0
- package/dist/db/export.js +37 -0
- package/dist/db/export.js.map +1 -0
- package/dist/db/manager.d.ts +62 -0
- package/dist/db/manager.js +206 -0
- package/dist/db/manager.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +10 -0
- package/dist/logger.js +25 -0
- package/dist/logger.js.map +1 -0
- package/dist/public/css/app.css +1 -0
- package/dist/public/css/input.css +179 -0
- package/dist/public/js/api.js +47 -0
- package/dist/public/js/app.js +120 -0
- package/dist/public/js/browse.js +123 -0
- package/dist/public/js/databases.js +45 -0
- package/dist/public/js/designer.js +205 -0
- package/dist/public/js/forms.js +244 -0
- package/dist/public/js/query.js +232 -0
- package/dist/public/js/schema.js +314 -0
- package/dist/public/js/triggers.js +155 -0
- package/dist/public/js/views.js +176 -0
- package/dist/routes/api.d.ts +9 -0
- package/dist/routes/api.js +622 -0
- package/dist/routes/api.js.map +1 -0
- package/dist/routes/databases.d.ts +19 -0
- package/dist/routes/databases.js +99 -0
- package/dist/routes/databases.js.map +1 -0
- package/dist/routes/pages.d.ts +9 -0
- package/dist/routes/pages.js +253 -0
- package/dist/routes/pages.js.map +1 -0
- package/dist/sql/classifier.d.ts +19 -0
- package/dist/sql/classifier.js +37 -0
- package/dist/sql/classifier.js.map +1 -0
- package/dist/sql/generator.d.ts +99 -0
- package/dist/sql/generator.js +259 -0
- package/dist/sql/generator.js.map +1 -0
- package/dist/test/classifier.test.d.ts +1 -0
- package/dist/test/classifier.test.js +44 -0
- package/dist/test/classifier.test.js.map +1 -0
- package/dist/test/csv.test.d.ts +1 -0
- package/dist/test/csv.test.js +64 -0
- package/dist/test/csv.test.js.map +1 -0
- package/dist/test/database.test.d.ts +1 -0
- package/dist/test/database.test.js +224 -0
- package/dist/test/database.test.js.map +1 -0
- package/dist/test/generator.test.d.ts +1 -0
- package/dist/test/generator.test.js +164 -0
- package/dist/test/generator.test.js.map +1 -0
- package/dist/test/manager.test.d.ts +1 -0
- package/dist/test/manager.test.js +146 -0
- package/dist/test/manager.test.js.map +1 -0
- package/dist/util.d.ts +29 -0
- package/dist/util.js +127 -0
- package/dist/util.js.map +1 -0
- package/dist/views/layouts/main.hbs +49 -0
- package/dist/views/pages/databases.hbs +102 -0
- package/dist/views/pages/designer.hbs +81 -0
- package/dist/views/pages/error.hbs +12 -0
- package/dist/views/pages/form.hbs +62 -0
- package/dist/views/pages/home.hbs +123 -0
- package/dist/views/pages/query.hbs +94 -0
- package/dist/views/pages/schema.hbs +290 -0
- package/dist/views/pages/table.hbs +203 -0
- package/dist/views/pages/triggers.hbs +162 -0
- package/dist/views/pages/views.hbs +134 -0
- package/dist/views/partials/navbar.hbs +50 -0
- package/dist/views/partials/sidebar.hbs +128 -0
- package/package.json +62 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { LogLevel } from './logger';
|
|
2
|
+
export interface Config {
|
|
3
|
+
host: string;
|
|
4
|
+
port: number;
|
|
5
|
+
/** Single-database file (used when no multi-db sources are configured). */
|
|
6
|
+
dbPath: string;
|
|
7
|
+
/** Directory of managed database files (multi-db mode source 1). */
|
|
8
|
+
dbDir?: string;
|
|
9
|
+
/** Explicit database file locations (multi-db mode source 2). */
|
|
10
|
+
dbFiles?: string[];
|
|
11
|
+
basePath: string;
|
|
12
|
+
logLevel: LogLevel;
|
|
13
|
+
/** Open the database read-only (writes disabled). */
|
|
14
|
+
readonly: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** Load configuration from environment variables with sensible defaults. */
|
|
17
|
+
export declare function loadConfig(env?: NodeJS.ProcessEnv): Config;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadConfig = loadConfig;
|
|
4
|
+
/** Load configuration from environment variables with sensible defaults. */
|
|
5
|
+
function loadConfig(env = process.env) {
|
|
6
|
+
const port = Number.parseInt(env.PORT ?? '3000', 10);
|
|
7
|
+
return {
|
|
8
|
+
host: env.HOST ?? '0.0.0.0',
|
|
9
|
+
port: Number.isFinite(port) ? port : 3000,
|
|
10
|
+
dbPath: env.DB_PATH ?? 'admindb.db',
|
|
11
|
+
dbDir: env.DB_DIR ? String(env.DB_DIR) : undefined,
|
|
12
|
+
dbFiles: env.DB_FILES
|
|
13
|
+
? String(env.DB_FILES)
|
|
14
|
+
.split(',')
|
|
15
|
+
.map((s) => s.trim())
|
|
16
|
+
.filter(Boolean)
|
|
17
|
+
: undefined,
|
|
18
|
+
basePath: (env.BASE_PATH ?? '').replace(/\/+$/, ''),
|
|
19
|
+
logLevel: (env.LOG_LEVEL ?? 'info'),
|
|
20
|
+
readonly: ['1', 'true', 'yes', 'on'].includes(String(env.READONLY ?? '').trim().toLowerCase()),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAkBA,gCAiBC;AAlBD,4EAA4E;AAC5E,SAAgB,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IACrD,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,SAAS;QAC3B,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QACzC,MAAM,EAAE,GAAG,CAAC,OAAO,IAAI,YAAY;QACnC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QAClD,OAAO,EAAE,GAAG,CAAC,QAAQ;YACnB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;iBACjB,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,MAAM,CAAC,OAAO,CAAC;YACpB,CAAC,CAAC,SAAS;QACb,QAAQ,EAAE,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACnD,QAAQ,EAAE,CAAE,GAAG,CAAC,SAAsB,IAAI,MAAM,CAAC;QACjD,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;KAC/F,CAAC;AACJ,CAAC"}
|
package/dist/csv.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal RFC 4180-style CSV serialization and parsing, used for table and
|
|
3
|
+
* query export/import. Pure functions with no I/O so they are easy to test.
|
|
4
|
+
*/
|
|
5
|
+
/** Escape a single CSV field (quote when it contains comma, quote or newline). */
|
|
6
|
+
export declare function csvEscape(value: unknown): string;
|
|
7
|
+
/** Serialize rows to CSV with an explicit column order. */
|
|
8
|
+
export declare function toCsv(rows: Record<string, unknown>[], columns: string[]): string;
|
|
9
|
+
/** Serialize rows to JSON (values are expected to be already normalized). */
|
|
10
|
+
export declare function toJson(rows: Record<string, unknown>[]): string;
|
|
11
|
+
/**
|
|
12
|
+
* Parse CSV text into rows of string fields. Handles quoted fields containing
|
|
13
|
+
* commas, quotes and embedded newlines. Blank lines are skipped.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseCsv(text: string): string[][];
|
package/dist/csv.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal RFC 4180-style CSV serialization and parsing, used for table and
|
|
4
|
+
* query export/import. Pure functions with no I/O so they are easy to test.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.csvEscape = csvEscape;
|
|
8
|
+
exports.toCsv = toCsv;
|
|
9
|
+
exports.toJson = toJson;
|
|
10
|
+
exports.parseCsv = parseCsv;
|
|
11
|
+
/** Escape a single CSV field (quote when it contains comma, quote or newline). */
|
|
12
|
+
function csvEscape(value) {
|
|
13
|
+
const s = value === null || value === undefined ? '' : String(value);
|
|
14
|
+
if (/[",\r\n]/.test(s))
|
|
15
|
+
return `"${s.replace(/"/g, '""')}"`;
|
|
16
|
+
return s;
|
|
17
|
+
}
|
|
18
|
+
/** Serialize rows to CSV with an explicit column order. */
|
|
19
|
+
function toCsv(rows, columns) {
|
|
20
|
+
const header = columns.map(csvEscape).join(',');
|
|
21
|
+
const body = rows.map((row) => columns.map((c) => csvEscape(row[c])).join(','));
|
|
22
|
+
return [header, ...body].join('\r\n');
|
|
23
|
+
}
|
|
24
|
+
/** Serialize rows to JSON (values are expected to be already normalized). */
|
|
25
|
+
function toJson(rows) {
|
|
26
|
+
return JSON.stringify(rows, null, 2);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parse CSV text into rows of string fields. Handles quoted fields containing
|
|
30
|
+
* commas, quotes and embedded newlines. Blank lines are skipped.
|
|
31
|
+
*/
|
|
32
|
+
function parseCsv(text) {
|
|
33
|
+
const rows = [];
|
|
34
|
+
let row = [];
|
|
35
|
+
let field = '';
|
|
36
|
+
let inQuotes = false;
|
|
37
|
+
const src = String(text ?? '');
|
|
38
|
+
for (let i = 0; i < src.length; i++) {
|
|
39
|
+
const ch = src[i];
|
|
40
|
+
if (inQuotes) {
|
|
41
|
+
if (ch === '"') {
|
|
42
|
+
if (src[i + 1] === '"') {
|
|
43
|
+
field += '"';
|
|
44
|
+
i++;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
inQuotes = false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
field += ch;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (ch === '"') {
|
|
55
|
+
inQuotes = true;
|
|
56
|
+
}
|
|
57
|
+
else if (ch === ',') {
|
|
58
|
+
row.push(field);
|
|
59
|
+
field = '';
|
|
60
|
+
}
|
|
61
|
+
else if (ch === '\n') {
|
|
62
|
+
row.push(field);
|
|
63
|
+
field = '';
|
|
64
|
+
if (row.length > 1 || row[0] !== '')
|
|
65
|
+
rows.push(row);
|
|
66
|
+
row = [];
|
|
67
|
+
}
|
|
68
|
+
else if (ch === '\r') {
|
|
69
|
+
// Ignore — part of CRLF line endings.
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
field += ch;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
row.push(field);
|
|
76
|
+
if (row.length > 1 || row[0] !== '')
|
|
77
|
+
rows.push(row);
|
|
78
|
+
return rows;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=csv.js.map
|
package/dist/csv.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv.js","sourceRoot":"","sources":["../src/csv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { type SQLInputValue } from 'node:sqlite';
|
|
2
|
+
import type { Logger } from '../logger';
|
|
3
|
+
import { type ColumnDef, type IndexDef, type TriggerDef } from '../sql/generator';
|
|
4
|
+
export interface Result<T = unknown> {
|
|
5
|
+
success: boolean;
|
|
6
|
+
data?: T;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface TableListItem {
|
|
10
|
+
name: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ColumnInfo {
|
|
13
|
+
cid: number;
|
|
14
|
+
name: string;
|
|
15
|
+
type: string;
|
|
16
|
+
notnull: number;
|
|
17
|
+
dflt_value: string | null;
|
|
18
|
+
pk: number;
|
|
19
|
+
}
|
|
20
|
+
export interface ForeignKeyInfo {
|
|
21
|
+
id: number;
|
|
22
|
+
seq: number;
|
|
23
|
+
table: string;
|
|
24
|
+
from: string;
|
|
25
|
+
to: string | null;
|
|
26
|
+
on_update: string;
|
|
27
|
+
on_delete: string;
|
|
28
|
+
}
|
|
29
|
+
export interface TableInfoData {
|
|
30
|
+
table: string;
|
|
31
|
+
columns: ColumnInfo[];
|
|
32
|
+
foreignKeys: ForeignKeyInfo[];
|
|
33
|
+
primaryKey: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface SavedQuery {
|
|
36
|
+
id: number;
|
|
37
|
+
name: string;
|
|
38
|
+
sql: string;
|
|
39
|
+
created_at: string;
|
|
40
|
+
}
|
|
41
|
+
export interface WhereClause {
|
|
42
|
+
column: string;
|
|
43
|
+
value: unknown;
|
|
44
|
+
}
|
|
45
|
+
export interface IndexInfo {
|
|
46
|
+
name: string;
|
|
47
|
+
unique: boolean;
|
|
48
|
+
partial: number;
|
|
49
|
+
/** Index origin: 'c' = explicit CREATE INDEX, 'pk'/'u' = automatic (primary key / unique). */
|
|
50
|
+
origin: string;
|
|
51
|
+
columns: string[];
|
|
52
|
+
/** The `CREATE INDEX` statement from sqlite_master, when available. */
|
|
53
|
+
sql?: string | null;
|
|
54
|
+
}
|
|
55
|
+
export interface ViewInfo {
|
|
56
|
+
name: string;
|
|
57
|
+
/** The `CREATE VIEW …` statement from sqlite_master. */
|
|
58
|
+
sql: string | null;
|
|
59
|
+
}
|
|
60
|
+
export interface TriggerInfo {
|
|
61
|
+
name: string;
|
|
62
|
+
/** The table (or view) the trigger fires on. */
|
|
63
|
+
table: string;
|
|
64
|
+
/** The `CREATE TRIGGER …` statement from sqlite_master. */
|
|
65
|
+
sql: string | null;
|
|
66
|
+
}
|
|
67
|
+
export interface RowFilters {
|
|
68
|
+
[column: string]: string;
|
|
69
|
+
}
|
|
70
|
+
export interface ColumnDetail extends ColumnInfo {
|
|
71
|
+
unique: boolean;
|
|
72
|
+
indexed: boolean;
|
|
73
|
+
/** Foreign keys in OTHER tables whose referenced column is this column. */
|
|
74
|
+
referencedBy: {
|
|
75
|
+
table: string;
|
|
76
|
+
from: string;
|
|
77
|
+
}[];
|
|
78
|
+
/** The foreign key this column participates in (as the child), if any. */
|
|
79
|
+
fk: ForeignKeyInfo | null;
|
|
80
|
+
canDrop: boolean;
|
|
81
|
+
dropBlockers: string[];
|
|
82
|
+
}
|
|
83
|
+
export interface SchemaInfo {
|
|
84
|
+
table: string;
|
|
85
|
+
columns: ColumnDetail[];
|
|
86
|
+
foreignKeys: ForeignKeyInfo[];
|
|
87
|
+
indexes: IndexInfo[];
|
|
88
|
+
/** Foreign keys in other tables that reference this table. */
|
|
89
|
+
references: {
|
|
90
|
+
table: string;
|
|
91
|
+
from: string;
|
|
92
|
+
to: string;
|
|
93
|
+
}[];
|
|
94
|
+
}
|
|
95
|
+
export declare const INTERNAL_TABLES: {
|
|
96
|
+
readonly savedQueries: "_saved_queries";
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Build a parameterized WHERE clause from per-column filters.
|
|
100
|
+
* Supported syntax in a filter value:
|
|
101
|
+
* - `=value` exact match, `!=value` not-equal, `>value`, `>=value`, `<value`, `<=value`
|
|
102
|
+
* - `value*` prefix match
|
|
103
|
+
* - anything else → case-insensitive substring (LIKE '%value%')
|
|
104
|
+
*/
|
|
105
|
+
export declare function buildFilterClause(filters: RowFilters | undefined, availableCols: string[]): {
|
|
106
|
+
where: string;
|
|
107
|
+
params: SQLInputValue[];
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Promise-style wrapper around the standard Node `node:sqlite` driver.
|
|
111
|
+
* Every call returns a consistent `{ success, data?, error? }` shape and
|
|
112
|
+
* performs one-time, idempotent schema initialization.
|
|
113
|
+
*/
|
|
114
|
+
export interface DbOpenOptions {
|
|
115
|
+
/** Open the database read-only: every write is rejected. */
|
|
116
|
+
readonly?: boolean;
|
|
117
|
+
}
|
|
118
|
+
export declare class SqliteDatabase {
|
|
119
|
+
private db;
|
|
120
|
+
private logger;
|
|
121
|
+
readonly path: string;
|
|
122
|
+
/** True when this database was opened in read-only mode. */
|
|
123
|
+
readonly isReadOnly: boolean;
|
|
124
|
+
constructor(dbPath: string, logger: Logger, options?: DbOpenOptions);
|
|
125
|
+
/** Standard error returned for every write attempt in read-only mode. */
|
|
126
|
+
private readonlyBlocked;
|
|
127
|
+
close(): void;
|
|
128
|
+
private initSchema;
|
|
129
|
+
private tryRun;
|
|
130
|
+
private toBind;
|
|
131
|
+
all(sql: string, params?: SQLInputValue[]): Promise<Result<unknown[]>>;
|
|
132
|
+
run(sql: string, params?: SQLInputValue[]): Promise<Result<{
|
|
133
|
+
changes: number;
|
|
134
|
+
lastInsertRowid: number | null;
|
|
135
|
+
}>>;
|
|
136
|
+
execResult(sql: string): Promise<Result<{
|
|
137
|
+
changes?: number;
|
|
138
|
+
}>>;
|
|
139
|
+
/** Run a write statement, reporting row changes when it is a single statement. */
|
|
140
|
+
runWrite(sql: string): Promise<Result<{
|
|
141
|
+
changes?: number;
|
|
142
|
+
}>>;
|
|
143
|
+
listTables(): Promise<Result<TableListItem[]>>;
|
|
144
|
+
getTableInfo(table: string): Promise<Result<TableInfoData>>;
|
|
145
|
+
getRowCount(table: string, filters?: RowFilters): Promise<Result<number>>;
|
|
146
|
+
getRows(table: string, opts?: {
|
|
147
|
+
page?: number;
|
|
148
|
+
limit?: number;
|
|
149
|
+
orderBy?: string;
|
|
150
|
+
orderDir?: 'asc' | 'desc';
|
|
151
|
+
filters?: RowFilters;
|
|
152
|
+
}): Promise<Result<Record<string, unknown>[]>>;
|
|
153
|
+
getAllRows(table: string): Promise<Result<Record<string, unknown>[]>>;
|
|
154
|
+
getRow(table: string, where: WhereClause[]): Promise<Result<Record<string, unknown> | null>>;
|
|
155
|
+
insertRow(table: string, fields: WhereClause[]): Promise<Result<{
|
|
156
|
+
changes: number;
|
|
157
|
+
lastInsertRowid: number | null;
|
|
158
|
+
}>>;
|
|
159
|
+
/** Insert many rows (used by CSV import) inside a single transaction. */
|
|
160
|
+
insertRows(table: string, rows: WhereClause[][]): Promise<Result<{
|
|
161
|
+
inserted: number;
|
|
162
|
+
skipped: number;
|
|
163
|
+
}>>;
|
|
164
|
+
updateRow(table: string, fields: WhereClause[], where: WhereClause[]): Promise<Result<{
|
|
165
|
+
changes: number;
|
|
166
|
+
lastInsertRowid: number | null;
|
|
167
|
+
}>>;
|
|
168
|
+
deleteRow(table: string, where: WhereClause[]): Promise<Result<{
|
|
169
|
+
changes: number;
|
|
170
|
+
lastInsertRowid: number | null;
|
|
171
|
+
}>>;
|
|
172
|
+
getCreateStatement(table: string): Promise<Result<string | null>>;
|
|
173
|
+
listSavedQueries(): Promise<Result<SavedQuery[]>>;
|
|
174
|
+
saveQuery(name: string, sql: string): Promise<Result<{
|
|
175
|
+
changes: number;
|
|
176
|
+
lastInsertRowid: number | null;
|
|
177
|
+
}>>;
|
|
178
|
+
deleteSavedQuery(id: string | number): Promise<Result<{
|
|
179
|
+
changes: number;
|
|
180
|
+
lastInsertRowid: number | null;
|
|
181
|
+
}>>;
|
|
182
|
+
/**
|
|
183
|
+
* Detailed schema for a table: columns with constraint info, indexes,
|
|
184
|
+
* foreign keys, and which other tables reference it.
|
|
185
|
+
*/
|
|
186
|
+
getSchema(table: string): Promise<Result<SchemaInfo>>;
|
|
187
|
+
renameTable(oldName: string, newName: string): Promise<Result<{
|
|
188
|
+
changes?: number;
|
|
189
|
+
}>>;
|
|
190
|
+
addColumn(table: string, col: ColumnDef): Promise<Result<{
|
|
191
|
+
changes?: number;
|
|
192
|
+
}>>;
|
|
193
|
+
renameColumn(table: string, oldName: string, newName: string): Promise<Result<{
|
|
194
|
+
changes?: number;
|
|
195
|
+
}>>;
|
|
196
|
+
dropColumn(table: string, column: string): Promise<Result<{
|
|
197
|
+
changes?: number;
|
|
198
|
+
}>>;
|
|
199
|
+
dropTable(table: string): Promise<Result<{
|
|
200
|
+
changes?: number;
|
|
201
|
+
}>>;
|
|
202
|
+
createIndex(table: string, index: IndexDef): Promise<Result<{
|
|
203
|
+
changes?: number;
|
|
204
|
+
}>>;
|
|
205
|
+
dropIndex(indexName: string): Promise<Result<{
|
|
206
|
+
changes?: number;
|
|
207
|
+
}>>;
|
|
208
|
+
listViews(): Promise<Result<ViewInfo[]>>;
|
|
209
|
+
/** Preview the first `limit` rows of a view (browse). */
|
|
210
|
+
getViewRows(viewName: string, limit?: number): Promise<Result<Record<string, unknown>[]>>;
|
|
211
|
+
createView(name: string, selectSql: string): Promise<Result<{
|
|
212
|
+
changes?: number;
|
|
213
|
+
}>>;
|
|
214
|
+
dropView(name: string): Promise<Result<{
|
|
215
|
+
changes?: number;
|
|
216
|
+
}>>;
|
|
217
|
+
listTriggers(): Promise<Result<TriggerInfo[]>>;
|
|
218
|
+
createTrigger(def: TriggerDef): Promise<Result<{
|
|
219
|
+
changes?: number;
|
|
220
|
+
}>>;
|
|
221
|
+
dropTrigger(name: string): Promise<Result<{
|
|
222
|
+
changes?: number;
|
|
223
|
+
}>>;
|
|
224
|
+
private getTableInfoSync;
|
|
225
|
+
}
|