masterrecord 0.3.18 → 0.3.19
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/package.json +1 -1
- package/readme.md +111 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "masterrecord",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.19",
|
|
4
4
|
"description": "An Object-relational mapping for the Master framework. Master Record connects classes to relational database tables to establish a database with almost zero-configuration ",
|
|
5
5
|
"main": "MasterRecord.js",
|
|
6
6
|
"bin": {
|
package/readme.md
CHANGED
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
| Database | Version | Features |
|
|
24
24
|
|------------|--------------|---------------------------------------------------|
|
|
25
25
|
| PostgreSQL | 9.6+ (12+) | JSONB, UUID, async/await, connection pooling |
|
|
26
|
-
| MySQL | 5.7+ (8.0+) | JSON,
|
|
27
|
-
| SQLite | 3.x | Embedded, zero-config, file-based
|
|
26
|
+
| MySQL | 5.7+ (8.0+) | JSON, async/await, connection pooling, AUTO_INCREMENT |
|
|
27
|
+
| SQLite | 3.x | Embedded, zero-config, file-based, async API wrapper |
|
|
28
28
|
|
|
29
29
|
## Table of Contents
|
|
30
30
|
|
|
@@ -64,9 +64,9 @@ npm install masterrecord better-sqlite3 # SQLite
|
|
|
64
64
|
### Dependencies
|
|
65
65
|
|
|
66
66
|
MasterRecord includes the following database drivers by default:
|
|
67
|
-
- `pg@^8.17.2` - PostgreSQL
|
|
68
|
-
- `
|
|
69
|
-
- `better-sqlite3@^12.6.2` - SQLite
|
|
67
|
+
- `pg@^8.17.2` - PostgreSQL (async)
|
|
68
|
+
- `mysql2@^3.11.5` - MySQL (async with connection pooling)
|
|
69
|
+
- `better-sqlite3@^12.6.2` - SQLite (async API wrapper for consistency)
|
|
70
70
|
|
|
71
71
|
## Two Patterns: Entity Framework & Active Record
|
|
72
72
|
|
|
@@ -212,7 +212,7 @@ const db = new AppContext();
|
|
|
212
212
|
await db.saveChanges(); // PostgreSQL is async
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
-
### MySQL (
|
|
215
|
+
### MySQL (Async with Connection Pooling)
|
|
216
216
|
|
|
217
217
|
```javascript
|
|
218
218
|
class AppContext extends context {
|
|
@@ -225,19 +225,20 @@ class AppContext extends context {
|
|
|
225
225
|
port: 3306,
|
|
226
226
|
database: 'myapp',
|
|
227
227
|
user: 'root',
|
|
228
|
-
password: 'password'
|
|
228
|
+
password: 'password',
|
|
229
|
+
connectionLimit: 10 // Connection pool size (optional)
|
|
229
230
|
});
|
|
230
231
|
|
|
231
232
|
this.dbset(User);
|
|
232
233
|
}
|
|
233
234
|
}
|
|
234
235
|
|
|
235
|
-
// Usage
|
|
236
|
+
// Usage requires await (async like PostgreSQL)
|
|
236
237
|
const db = new AppContext();
|
|
237
|
-
db.saveChanges(); //
|
|
238
|
+
await db.saveChanges(); // MySQL now uses async/await
|
|
238
239
|
```
|
|
239
240
|
|
|
240
|
-
### SQLite (
|
|
241
|
+
### SQLite (Async API)
|
|
241
242
|
|
|
242
243
|
```javascript
|
|
243
244
|
class AppContext extends context {
|
|
@@ -252,6 +253,10 @@ class AppContext extends context {
|
|
|
252
253
|
this.dbset(User);
|
|
253
254
|
}
|
|
254
255
|
}
|
|
256
|
+
|
|
257
|
+
// Usage requires await for consistency across databases
|
|
258
|
+
const db = new AppContext();
|
|
259
|
+
await db.saveChanges(); // SQLite now has async API wrapper
|
|
255
260
|
```
|
|
256
261
|
|
|
257
262
|
### Environment Files
|
|
@@ -593,33 +598,48 @@ masterrecord update-database-all # Apply all pending migrations
|
|
|
593
598
|
|
|
594
599
|
```javascript
|
|
595
600
|
// db/migrations/20250111_143052_CreateUser.js
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
601
|
+
const masterrecord = require('masterrecord');
|
|
602
|
+
|
|
603
|
+
class CreateUser extends masterrecord.schema {
|
|
604
|
+
constructor(context) {
|
|
605
|
+
super(context);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// IMPORTANT: Migrations must be async
|
|
609
|
+
async up(table) {
|
|
610
|
+
this.init(table);
|
|
611
|
+
|
|
612
|
+
// Create table (requires await)
|
|
613
|
+
await this.createTable(table.User);
|
|
600
614
|
|
|
601
615
|
// Seed initial data
|
|
602
|
-
|
|
616
|
+
this.seed('User', {
|
|
603
617
|
name: 'Admin',
|
|
604
618
|
email: 'admin@example.com',
|
|
605
619
|
role: 'admin'
|
|
606
620
|
});
|
|
607
|
-
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
async down(table) {
|
|
624
|
+
this.init(table);
|
|
608
625
|
|
|
609
|
-
down: function(table, schema) {
|
|
610
626
|
// Rollback
|
|
611
|
-
|
|
627
|
+
this.dropTable(table.User);
|
|
612
628
|
}
|
|
613
|
-
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
module.exports = CreateUser;
|
|
614
632
|
```
|
|
615
633
|
|
|
616
634
|
### Migration Operations
|
|
617
635
|
|
|
618
636
|
```javascript
|
|
619
|
-
|
|
620
|
-
up
|
|
621
|
-
|
|
622
|
-
|
|
637
|
+
class MyMigration extends masterrecord.schema {
|
|
638
|
+
async up(table) {
|
|
639
|
+
this.init(table);
|
|
640
|
+
|
|
641
|
+
// Create table (requires await)
|
|
642
|
+
await this.createTable(table.User);
|
|
623
643
|
|
|
624
644
|
// Add column
|
|
625
645
|
schema.addColumn({
|
|
@@ -1189,9 +1209,8 @@ const users = db._SQLEngine.exec(
|
|
|
1189
1209
|
context.dbset(EntityClass)
|
|
1190
1210
|
context.dbset(EntityClass, 'custom_table_name')
|
|
1191
1211
|
|
|
1192
|
-
// Save changes
|
|
1193
|
-
await context.saveChanges() // PostgreSQL (async)
|
|
1194
|
-
context.saveChanges() // MySQL/SQLite (sync)
|
|
1212
|
+
// Save changes (all databases now async)
|
|
1213
|
+
await context.saveChanges() // PostgreSQL, MySQL, SQLite (all async)
|
|
1195
1214
|
|
|
1196
1215
|
// Add/Remove entities
|
|
1197
1216
|
context.EntityName.add(entity)
|
|
@@ -1585,9 +1604,9 @@ user.name = null; // Error if name is { nullable: false }
|
|
|
1585
1604
|
| PostgreSQL | 9.6+ (12+) | Tested with 12, 13, 14, 15, 16 |
|
|
1586
1605
|
| MySQL | 5.7+ (8.0+) | Tested with 8.0+ |
|
|
1587
1606
|
| SQLite | 3.x | Any recent version |
|
|
1588
|
-
| pg | 8.17.2+ | PostgreSQL driver
|
|
1589
|
-
|
|
|
1590
|
-
| better-sqlite3| 12.6.2+ | SQLite driver
|
|
1607
|
+
| pg | 8.17.2+ | PostgreSQL driver (async) |
|
|
1608
|
+
| mysql2 | 3.11.5+ | MySQL driver (async with connection pooling) |
|
|
1609
|
+
| better-sqlite3| 12.6.2+ | SQLite driver (wrapped with async API) |
|
|
1591
1610
|
|
|
1592
1611
|
## Documentation
|
|
1593
1612
|
|
|
@@ -1814,19 +1833,75 @@ $ grep -A1 "catch.*{$" insertManager.js | grep "^\s*}$"
|
|
|
1814
1833
|
# ✅ No empty catch blocks - all log errors appropriately
|
|
1815
1834
|
```
|
|
1816
1835
|
|
|
1817
|
-
### Breaking Changes
|
|
1836
|
+
### Breaking Changes (v0.3.17+)
|
|
1837
|
+
|
|
1838
|
+
**🔴 CRITICAL: All databases now require async/await for consistency**
|
|
1839
|
+
|
|
1840
|
+
MasterRecord now provides a **unified async API** across all database engines (SQLite, MySQL, PostgreSQL). This follows industry best practices from Sequelize, TypeORM, and Prisma.
|
|
1818
1841
|
|
|
1819
|
-
**
|
|
1842
|
+
**1. Database Operations (All Engines)**
|
|
1820
1843
|
```javascript
|
|
1821
|
-
//
|
|
1844
|
+
// ✅ NEW (v0.3.17+): All databases use async/await
|
|
1822
1845
|
const db = new AppContext();
|
|
1823
|
-
await db.
|
|
1846
|
+
await db.saveChanges(); // Required for SQLite, MySQL, PostgreSQL
|
|
1824
1847
|
|
|
1825
|
-
//
|
|
1826
|
-
|
|
1827
|
-
db.
|
|
1848
|
+
// ❌ OLD (v0.3.16 and earlier): Mixed sync/async
|
|
1849
|
+
db.saveChanges(); // SQLite/MySQL were sync (no longer works)
|
|
1850
|
+
await db.saveChanges(); // Only PostgreSQL was async
|
|
1828
1851
|
```
|
|
1829
1852
|
|
|
1853
|
+
**2. Migration Files (Critical)**
|
|
1854
|
+
```javascript
|
|
1855
|
+
// ✅ NEW (v0.3.17+): Migrations must be async
|
|
1856
|
+
class CreateUser extends masterrecord.schema {
|
|
1857
|
+
async up(table) { // Must be async
|
|
1858
|
+
this.init(table);
|
|
1859
|
+
await this.createTable(table.User); // Must await
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
async down(table) { // Must be async
|
|
1863
|
+
this.init(table);
|
|
1864
|
+
this.dropTable(table.User);
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
// ❌ OLD (v0.3.16 and earlier): Migrations were sync
|
|
1869
|
+
up(table) {
|
|
1870
|
+
this.createTable(table.User); // No await (no longer works)
|
|
1871
|
+
}
|
|
1872
|
+
```
|
|
1873
|
+
|
|
1874
|
+
**3. MySQL Connection**
|
|
1875
|
+
```javascript
|
|
1876
|
+
// ✅ NEW (v0.3.17+): MySQL uses mysql2/promise with async connection pooling
|
|
1877
|
+
this.env({
|
|
1878
|
+
type: 'mysql',
|
|
1879
|
+
host: 'localhost',
|
|
1880
|
+
port: 3306,
|
|
1881
|
+
database: 'myapp',
|
|
1882
|
+
user: 'root',
|
|
1883
|
+
password: 'password',
|
|
1884
|
+
connectionLimit: 10 // Connection pool size
|
|
1885
|
+
});
|
|
1886
|
+
|
|
1887
|
+
// ❌ OLD (v0.3.16 and earlier): MySQL used sync-mysql2 (synchronous driver)
|
|
1888
|
+
```
|
|
1889
|
+
|
|
1890
|
+
**Why This Change?**
|
|
1891
|
+
- ✅ **Consistent API**: Same code works for SQLite, MySQL, and PostgreSQL
|
|
1892
|
+
- ✅ **Industry Standard**: Matches Sequelize, TypeORM, Prisma patterns
|
|
1893
|
+
- ✅ **Better Performance**: MySQL now uses connection pooling
|
|
1894
|
+
- ✅ **Real MySQL**: No longer using SQLite disguised as MySQL
|
|
1895
|
+
- ✅ **Portable Code**: Switch databases without code changes
|
|
1896
|
+
|
|
1897
|
+
**Migration Path:**
|
|
1898
|
+
1. Update all `db.saveChanges()` calls to use `await`
|
|
1899
|
+
2. Make all migration `up()` and `down()` methods async
|
|
1900
|
+
3. Add `await` before `createTable()` calls in migrations
|
|
1901
|
+
4. Update `package.json`: Remove `sync-mysql2`, ensure `mysql2@^3.11.5`
|
|
1902
|
+
|
|
1903
|
+
**For more details, see:** `CHANGES.md`
|
|
1904
|
+
|
|
1830
1905
|
**For more details, see:** `CHANGES.md`
|
|
1831
1906
|
|
|
1832
1907
|
---
|