Skip to content

Commit 8e68061

Browse files
committed
Implement schema validation add creation
1 parent e330627 commit 8e68061

File tree

3 files changed

+40
-19
lines changed

3 files changed

+40
-19
lines changed

Pragmatic/static/application.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@ class Logger {
2020

2121
const logger = new Logger('output');
2222
const schemas = {
23-
user: { keyPath: 'id', autoIncrement: true },
23+
user: {
24+
id: { type: 'int', primary: true },
25+
name: { type: 'str', index: true },
26+
age: { type: 'int' },
27+
},
2428
};
2529
const db = await new Database('Example', { version: 1, schemas });
2630

2731
const actions = {
2832
add: async () => {
2933
const name = prompt('Enter user name:');
30-
if (!name) return;
3134
const age = parseInt(prompt('Enter age:'), 10);
32-
if (!Number.isInteger(age)) return;
3335
const user = { name, age };
3436
await db.insert({ store: 'user', record: user });
3537
logger.log('Added:', user);

Pragmatic/static/storage.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ class Database {
3333
#upgrade(db) {
3434
for (const [name, schema] of Object.entries(this.#schemas)) {
3535
if (!db.objectStoreNames.contains(name)) {
36-
const store = db.createObjectStore(name, schema);
37-
const indexes = schema.indexes ?? [];
38-
for (const { name: idxName, keyPath, options } of indexes) {
39-
store.createIndex(idxName, keyPath, options);
36+
const options = { keyPath: 'id', autoIncrement: true };
37+
const store = db.createObjectStore(name, options);
38+
for (const [field, def] of Object.entries(schema)) {
39+
if (name !== 'id' && def.index) {
40+
store.createIndex(field, field, { unique: false });
41+
}
4042
}
4143
}
4244
}
@@ -59,11 +61,30 @@ class Database {
5961
});
6062
}
6163

64+
validate({ store, record }) {
65+
const schema = this.#schemas[store];
66+
if (!schema) throw new Error(`Schema for ${store} is not defined`);
67+
for (const [key, val] of Object.entries(record)) {
68+
const field = schema[key];
69+
const name = `Field ${store}.${key}`;
70+
if (!field) throw new Error(`${name} is not defined`);
71+
if (field.type === 'int') {
72+
if (Number.isInteger(val)) continue;
73+
throw new Error(`${name} expected to be integer`);
74+
} else if (field.type === 'str') {
75+
if (typeof val === 'string') continue;
76+
throw new Error(`${name} expected to be string`);
77+
}
78+
}
79+
}
80+
6281
insert({ store, record }) {
82+
this.validate({ store, record });
6383
return this.#exec(store, (objectStore) => objectStore.add(record));
6484
}
6585

6686
update({ store, record }) {
87+
this.validate({ store, record });
6788
return this.#exec(store, (objectStore) => objectStore.put(record));
6889
}
6990

Pragmatic/test/database.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import assert from 'node:assert/strict';
33
import 'fake-indexeddb/auto';
44
import { Database } from '../static/storage.js';
55

6+
const schemas = {
7+
user: {
8+
id: { type: 'int', primary: true },
9+
name: { type: 'str', index: true },
10+
age: { type: 'int' },
11+
},
12+
};
13+
614
test('Pragmatic: Database CRUD + DSL', async () => {
7-
const db = await new Database('PragmaticDB', {
8-
version: 1,
9-
schemas: {
10-
user: { keyPath: 'id', autoIncrement: true },
11-
},
12-
});
15+
const db = await new Database('PragmaticDB', { version: 1, schemas });
1316

1417
// Insert
1518
await db.insert({ store: 'user', record: { name: 'Marcus', age: 20 } });
@@ -74,12 +77,7 @@ test('Pragmatic: Database CRUD + DSL', async () => {
7477
});
7578

7679
test('Pragmatic: Complex DSL', async () => {
77-
const db = await new Database('ComplexDB', {
78-
version: 1,
79-
schemas: {
80-
user: { keyPath: 'id', autoIncrement: true },
81-
},
82-
});
80+
const db = await new Database('ComplexDB', { version: 1, schemas });
8381

8482
await db.insert({ store: 'user', record: { name: 'Marcus', age: 20 } });
8583
await db.insert({ store: 'user', record: { name: 'Lucius', age: 20 } });

0 commit comments

Comments
 (0)