@edadma/rdb 0.1.0-pre.40 → 0.1.5
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 +278 -0
- package/index.d.ts +116 -1
- package/main.js +118092 -64761
- package/package.json +16 -7
- package/edadma-rdb-0.1.0-pre.40.tgz +0 -0
- package/main.js.map +0 -8
package/README.md
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# @edadma/rdb
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@edadma/rdb)
|
|
4
|
+
|
|
5
|
+
A lightweight, in-memory SQL database for JavaScript and TypeScript. No native dependencies, no external services — just import and query. Follows PostgreSQL conventions for SQL syntax, identifier handling, and type casting.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @edadma/rdb
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
import { ConnectSQL } from '@edadma/rdb';
|
|
17
|
+
|
|
18
|
+
const db = new ConnectSQL();
|
|
19
|
+
|
|
20
|
+
db.execute(`
|
|
21
|
+
CREATE TABLE users (
|
|
22
|
+
id SERIAL,
|
|
23
|
+
name TEXT NOT NULL,
|
|
24
|
+
email TEXT,
|
|
25
|
+
PRIMARY KEY (id)
|
|
26
|
+
)
|
|
27
|
+
`);
|
|
28
|
+
|
|
29
|
+
db.execute("INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')");
|
|
30
|
+
db.execute("INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com')");
|
|
31
|
+
|
|
32
|
+
const [{ rows, fields }] = db.execute('SELECT * FROM users');
|
|
33
|
+
// rows: [{ id: 1, name: 'Alice', email: 'alice@example.com' }, ...]
|
|
34
|
+
// fields: [{ name: 'id', dataType: 'serial' }, { name: 'name', dataType: 'text' }, ...]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Row Modes
|
|
38
|
+
|
|
39
|
+
By default, SELECT rows are returned as objects keyed by column name. Use `rowMode: 'array'` for positional arrays instead.
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
// Set default for all queries
|
|
43
|
+
const db = new ConnectSQL({ rowMode: 'array' });
|
|
44
|
+
|
|
45
|
+
// Or override per call
|
|
46
|
+
const [{ rows }] = db.execute('SELECT id, name FROM users', { rowMode: 'array' });
|
|
47
|
+
// rows: [[1, 'Alice'], [2, 'Bob']]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## SQL Compatibility
|
|
51
|
+
|
|
52
|
+
RDB follows PostgreSQL conventions:
|
|
53
|
+
|
|
54
|
+
- **Case-insensitive keywords** — `SELECT`, `select`, and `Select` are equivalent
|
|
55
|
+
- **Unquoted identifier folding** — identifiers fold to lowercase (`CREATE TABLE Users` → table name `users`)
|
|
56
|
+
- **Double-quoted identifiers** — preserve case (`"MixedCase"` stays as-is)
|
|
57
|
+
- **String escaping** — doubled single quotes (`'it''s'`) and E-strings (`E'it\'s'`)
|
|
58
|
+
- **Operators** — both `!=` and `<>` for not-equal
|
|
59
|
+
- **Type casting** — `::` operator and `CAST(expr AS type)`
|
|
60
|
+
|
|
61
|
+
## Supported SQL
|
|
62
|
+
|
|
63
|
+
### Data Types
|
|
64
|
+
|
|
65
|
+
| Type | Description |
|
|
66
|
+
|------|-------------|
|
|
67
|
+
| `SMALLINT` | 16-bit integer |
|
|
68
|
+
| `INT` / `INTEGER` | 32-bit integer |
|
|
69
|
+
| `BIGINT` | 64-bit integer |
|
|
70
|
+
| `SMALLSERIAL` / `SERIAL` / `BIGSERIAL` | Auto-incrementing integers |
|
|
71
|
+
| `DOUBLE` / `FLOAT` / `REAL` | Double-precision float |
|
|
72
|
+
| `NUMERIC(p, s)` / `DECIMAL(p, s)` | Fixed-precision decimal |
|
|
73
|
+
| `TEXT` | Variable-length string |
|
|
74
|
+
| `CHAR(n)` | Fixed-length string |
|
|
75
|
+
| `BOOLEAN` | True/false |
|
|
76
|
+
| `DATE` / `TIME` / `TIMESTAMP` | Date and time types |
|
|
77
|
+
| `TIMESTAMP WITH TIME ZONE` | Timezone-aware timestamp |
|
|
78
|
+
| `INTERVAL` | Duration |
|
|
79
|
+
| `UUID` | UUID (use `DEFAULT gen_random_uuid()`) |
|
|
80
|
+
| `JSON` / `JSONB` | JSON objects and arrays |
|
|
81
|
+
| `BYTEA` | Binary data |
|
|
82
|
+
| `ENUM` | Custom enumerated types |
|
|
83
|
+
| `INT[]`, `TEXT[]`, etc. | Typed arrays |
|
|
84
|
+
|
|
85
|
+
### DDL
|
|
86
|
+
|
|
87
|
+
```sql
|
|
88
|
+
CREATE TABLE, CREATE TABLE IF NOT EXISTS
|
|
89
|
+
DROP TABLE, DROP TABLE IF EXISTS
|
|
90
|
+
ALTER TABLE (ADD/DROP/RENAME COLUMN, ADD CONSTRAINT, etc.)
|
|
91
|
+
CREATE TYPE ... AS ENUM, DROP TYPE
|
|
92
|
+
CREATE INDEX, CREATE UNIQUE INDEX, DROP INDEX
|
|
93
|
+
TRUNCATE TABLE
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### DML
|
|
97
|
+
|
|
98
|
+
```sql
|
|
99
|
+
INSERT INTO ... VALUES
|
|
100
|
+
INSERT INTO ... SELECT -- insert from a query
|
|
101
|
+
UPDATE ... SET ... WHERE
|
|
102
|
+
UPDATE ... SET ... FROM ... -- bulk update with join semantics
|
|
103
|
+
DELETE FROM ... WHERE
|
|
104
|
+
TRUNCATE TABLE -- fast table reset, resets serial sequences
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Queries
|
|
108
|
+
|
|
109
|
+
```sql
|
|
110
|
+
SELECT, SELECT DISTINCT, WHERE, ORDER BY, LIMIT, OFFSET
|
|
111
|
+
GROUP BY, HAVING
|
|
112
|
+
JOIN (INNER/LEFT/RIGHT/FULL/CROSS)
|
|
113
|
+
LATERAL joins -- correlated subqueries in FROM
|
|
114
|
+
Subqueries, EXISTS, IN, = ANY(...)
|
|
115
|
+
VALUES as standalone query and FROM source
|
|
116
|
+
Column aliases: AS alias (col1, col2, ...)
|
|
117
|
+
CASE expressions, BETWEEN, LIKE, ILIKE
|
|
118
|
+
UNION, INTERSECT, EXCEPT
|
|
119
|
+
OVERLAPS -- date/time range overlap test
|
|
120
|
+
CAST(expr AS type), expr::type
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Constraints
|
|
124
|
+
|
|
125
|
+
```sql
|
|
126
|
+
PRIMARY KEY, UNIQUE, NOT NULL, DEFAULT
|
|
127
|
+
FOREIGN KEY ... REFERENCES ... ON DELETE/UPDATE (CASCADE, SET NULL, RESTRICT)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Transactions
|
|
131
|
+
|
|
132
|
+
```sql
|
|
133
|
+
BEGIN, COMMIT, ROLLBACK
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Prepared Statements
|
|
137
|
+
|
|
138
|
+
```sql
|
|
139
|
+
PREPARE name AS statement -- with $1, $2, ... parameters
|
|
140
|
+
EXECUTE name(arg1, arg2, ...)
|
|
141
|
+
DEALLOCATE name
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Aggregate Functions
|
|
145
|
+
|
|
146
|
+
`COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, `string_agg`, `array_agg`, `bool_and`, `bool_or`, `variance`, `var_samp`, `var_pop`, `stddev`, `stddev_samp`, `stddev_pop`
|
|
147
|
+
|
|
148
|
+
### Built-in Functions
|
|
149
|
+
|
|
150
|
+
**Text:** `lower`, `upper`, `initcap`, `length`, `trim`, `ltrim`, `rtrim`, `substring`, `left`, `right`, `lpad`, `rpad`, `replace`, `concat`, `concat_ws`, `repeat`, `reverse`, `position`, `split_part`, `ascii`, `chr`, `regexp_replace`, `regexp_match`, `starts_with`, `ends_with`
|
|
151
|
+
|
|
152
|
+
**Numeric:** `abs`, `ceil`, `floor`, `round`, `trunc`, `sign`, `mod`, `power`, `sqrt`, `exp`, `ln`, `log10`, `log`, `pi`, `degrees`, `radians`, `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `random`, `greatest`, `least`
|
|
153
|
+
|
|
154
|
+
**Date/Time:** `now`, `current_date`, `current_time`, `date_part`, `EXTRACT`, `date_trunc`, `make_date`, `make_time`, `age`, `to_char`, `to_date`, `to_timestamp`
|
|
155
|
+
|
|
156
|
+
**Array:** `array_length`, `array_append`, `array_prepend`, `array_concat`, `array_slice`, `array_remove`, `array_position`, `array_distinct`, `string_to_array`, `array_to_string`
|
|
157
|
+
|
|
158
|
+
**Other:** `coalesce`, `nullif`, `typeof`, `gen_random_uuid`, `octet_length`, `encode`, `decode`
|
|
159
|
+
|
|
160
|
+
## API
|
|
161
|
+
|
|
162
|
+
### `new ConnectSQL(options?)`
|
|
163
|
+
|
|
164
|
+
Creates a new database instance. Each instance is fully isolated.
|
|
165
|
+
|
|
166
|
+
| Option | Type | Default | Description |
|
|
167
|
+
|--------|------|---------|-------------|
|
|
168
|
+
| `rowMode` | `'object' \| 'array'` | `'object'` | Default row format for SELECT results |
|
|
169
|
+
|
|
170
|
+
### `db.execute(sql, options?)`
|
|
171
|
+
|
|
172
|
+
Executes one or more SQL statements separated by `;`. Returns an array of results.
|
|
173
|
+
|
|
174
|
+
| Option | Type | Default | Description |
|
|
175
|
+
|--------|------|---------|-------------|
|
|
176
|
+
| `rowMode` | `'object' \| 'array'` | constructor default | Row format for this call |
|
|
177
|
+
|
|
178
|
+
### Result Types
|
|
179
|
+
|
|
180
|
+
Every result has a `command` field for easy discrimination:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
// DDL
|
|
184
|
+
{ command: 'create table', table: string }
|
|
185
|
+
{ command: 'drop table', table: string }
|
|
186
|
+
{ command: 'create type', type: string }
|
|
187
|
+
{ command: 'drop type', type: string }
|
|
188
|
+
{ command: 'create index', index: string }
|
|
189
|
+
{ command: 'drop index', index: string }
|
|
190
|
+
{ command: 'truncate table', table: string }
|
|
191
|
+
{ command: 'alter table' }
|
|
192
|
+
|
|
193
|
+
// DML
|
|
194
|
+
{ command: 'insert', result: Record<string, any> }
|
|
195
|
+
{ command: 'select', rows: T[], fields: { name: string, dataType: string }[] }
|
|
196
|
+
{ command: 'update', rows: number }
|
|
197
|
+
{ command: 'delete', rows: number }
|
|
198
|
+
|
|
199
|
+
// Transactions
|
|
200
|
+
{ command: 'begin' }
|
|
201
|
+
{ command: 'commit' }
|
|
202
|
+
{ command: 'rollback' }
|
|
203
|
+
|
|
204
|
+
// Prepared statements
|
|
205
|
+
{ command: 'prepare', name: string }
|
|
206
|
+
{ command: 'deallocate', name: string }
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Value Mapping
|
|
210
|
+
|
|
211
|
+
| SQL Type | JavaScript Type |
|
|
212
|
+
|----------|----------------|
|
|
213
|
+
| INT, BIGINT, DOUBLE, NUMERIC | `number` |
|
|
214
|
+
| TEXT, CHAR | `string` |
|
|
215
|
+
| BOOLEAN | `boolean` |
|
|
216
|
+
| UUID | `string` |
|
|
217
|
+
| TIMESTAMP | `Date` |
|
|
218
|
+
| ENUM | `string` (label) |
|
|
219
|
+
| JSON array | `Array` |
|
|
220
|
+
| JSON object | `Object` |
|
|
221
|
+
| NULL | `null` |
|
|
222
|
+
|
|
223
|
+
## TypeScript
|
|
224
|
+
|
|
225
|
+
Full type definitions are included. Use discriminated unions to narrow result types:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
import { ConnectSQL, ExecuteResult } from '@edadma/rdb';
|
|
229
|
+
|
|
230
|
+
const db = new ConnectSQL();
|
|
231
|
+
const results: ExecuteResult[] = db.execute('SELECT * FROM users');
|
|
232
|
+
|
|
233
|
+
for (const result of results) {
|
|
234
|
+
if (result.command === 'select') {
|
|
235
|
+
// result.rows and result.fields are typed here
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Example
|
|
241
|
+
|
|
242
|
+
```javascript
|
|
243
|
+
import { ConnectSQL } from '@edadma/rdb';
|
|
244
|
+
|
|
245
|
+
const db = new ConnectSQL();
|
|
246
|
+
|
|
247
|
+
db.execute(`
|
|
248
|
+
CREATE TYPE status AS ENUM ('active', 'inactive');
|
|
249
|
+
CREATE TABLE products (
|
|
250
|
+
id SERIAL,
|
|
251
|
+
name TEXT NOT NULL,
|
|
252
|
+
price NUMERIC(10,2),
|
|
253
|
+
status status DEFAULT 'active',
|
|
254
|
+
tags JSON,
|
|
255
|
+
created_at TIMESTAMP,
|
|
256
|
+
PRIMARY KEY (id)
|
|
257
|
+
)
|
|
258
|
+
`);
|
|
259
|
+
|
|
260
|
+
db.execute(`
|
|
261
|
+
INSERT INTO products (name, price, tags, created_at) VALUES
|
|
262
|
+
('Laptop', 999.99, '["electronics", "computers"]', '2025-01-15 10:30:00');
|
|
263
|
+
INSERT INTO products (name, price, tags, created_at) VALUES
|
|
264
|
+
('Coffee', 4.50, '["food", "organic"]', '2025-01-16 08:00:00')
|
|
265
|
+
`);
|
|
266
|
+
|
|
267
|
+
const [{ rows }] = db.execute(`
|
|
268
|
+
SELECT name, price FROM products
|
|
269
|
+
WHERE price > 10
|
|
270
|
+
ORDER BY price DESC
|
|
271
|
+
`);
|
|
272
|
+
|
|
273
|
+
console.log(rows); // [{ name: 'Laptop', price: 999.99 }]
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## License
|
|
277
|
+
|
|
278
|
+
[ISC](https://opensource.org/licenses/ISC)
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,118 @@
|
|
|
1
|
+
export interface ConnectSQLOptions {
|
|
2
|
+
rowMode?: 'object' | 'array';
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface ExecuteOptions {
|
|
6
|
+
rowMode?: 'object' | 'array';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface FieldInfo {
|
|
10
|
+
name: string;
|
|
11
|
+
dataType: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CreateTableResult {
|
|
15
|
+
command: 'create table';
|
|
16
|
+
table: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface DropTableResult {
|
|
20
|
+
command: 'drop table';
|
|
21
|
+
table: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface CreateTypeResult {
|
|
25
|
+
command: 'create type';
|
|
26
|
+
type: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface DropTypeResult {
|
|
30
|
+
command: 'drop type';
|
|
31
|
+
type: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface CreateIndexResult {
|
|
35
|
+
command: 'create index';
|
|
36
|
+
index: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface DropIndexResult {
|
|
40
|
+
command: 'drop index';
|
|
41
|
+
index: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface TruncateTableResult {
|
|
45
|
+
command: 'truncate table';
|
|
46
|
+
table: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface AlterTableResult {
|
|
50
|
+
command: 'alter table';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface PrepareResult {
|
|
54
|
+
command: 'prepare';
|
|
55
|
+
name: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface DeallocateResult {
|
|
59
|
+
command: 'deallocate';
|
|
60
|
+
name: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface BeginResult {
|
|
64
|
+
command: 'begin';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface CommitResult {
|
|
68
|
+
command: 'commit';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface RollbackResult {
|
|
72
|
+
command: 'rollback';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface InsertResult {
|
|
76
|
+
command: 'insert';
|
|
77
|
+
result: Record<string, any>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface SelectResult<T = Record<string, any>> {
|
|
81
|
+
command: 'select';
|
|
82
|
+
rows: T[];
|
|
83
|
+
fields: FieldInfo[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface UpdateResult {
|
|
87
|
+
command: 'update';
|
|
88
|
+
rows: number;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface DeleteResult {
|
|
92
|
+
command: 'delete';
|
|
93
|
+
rows: number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type ExecuteResult =
|
|
97
|
+
| CreateTableResult
|
|
98
|
+
| DropTableResult
|
|
99
|
+
| CreateTypeResult
|
|
100
|
+
| DropTypeResult
|
|
101
|
+
| CreateIndexResult
|
|
102
|
+
| DropIndexResult
|
|
103
|
+
| TruncateTableResult
|
|
104
|
+
| AlterTableResult
|
|
105
|
+
| InsertResult
|
|
106
|
+
| SelectResult
|
|
107
|
+
| UpdateResult
|
|
108
|
+
| DeleteResult
|
|
109
|
+
| PrepareResult
|
|
110
|
+
| DeallocateResult
|
|
111
|
+
| BeginResult
|
|
112
|
+
| CommitResult
|
|
113
|
+
| RollbackResult;
|
|
114
|
+
|
|
1
115
|
export class ConnectSQL {
|
|
2
|
-
|
|
116
|
+
constructor(options?: ConnectSQLOptions);
|
|
117
|
+
execute(sql: string, options?: ExecuteOptions): ExecuteResult[];
|
|
3
118
|
}
|