meadow 2.0.23 → 2.0.26
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 +110 -141
- package/docs/README.md +34 -230
- package/docs/_cover.md +14 -0
- package/docs/_sidebar.md +44 -12
- package/docs/_topbar.md +5 -0
- package/docs/api/doCount.md +109 -0
- package/docs/api/doCreate.md +132 -0
- package/docs/api/doDelete.md +101 -0
- package/docs/api/doRead.md +122 -0
- package/docs/api/doReads.md +136 -0
- package/docs/api/doUndelete.md +98 -0
- package/docs/api/doUpdate.md +129 -0
- package/docs/api/getRoleName.md +84 -0
- package/docs/api/loadFromPackage.md +153 -0
- package/docs/api/marshalRecordFromSourceToObject.md +92 -0
- package/docs/api/query.md +133 -0
- package/docs/api/rawQueries.md +197 -0
- package/docs/api/reference.md +117 -0
- package/docs/api/setAuthorizer.md +103 -0
- package/docs/api/setDefault.md +90 -0
- package/docs/api/setDefaultIdentifier.md +84 -0
- package/docs/api/setDomain.md +56 -0
- package/docs/api/setIDUser.md +91 -0
- package/docs/api/setJsonSchema.md +92 -0
- package/docs/api/setProvider.md +87 -0
- package/docs/api/setSchema.md +107 -0
- package/docs/api/setScope.md +68 -0
- package/docs/api/validateObject.md +119 -0
- package/docs/architecture.md +316 -0
- package/docs/audit-tracking.md +226 -0
- package/docs/configuration.md +317 -0
- package/docs/providers/meadow-endpoints.md +306 -0
- package/docs/providers/mongodb.md +319 -0
- package/docs/providers/postgresql.md +312 -0
- package/docs/providers/rocksdb.md +297 -0
- package/docs/query-dsl.md +269 -0
- package/docs/quick-start.md +384 -0
- package/docs/raw-queries.md +193 -0
- package/docs/retold-catalog.json +61 -1
- package/docs/retold-keyword-index.json +15860 -4839
- package/docs/soft-deletes.md +224 -0
- package/package.json +36 -9
- package/scripts/bookstore-seed-postgresql.sql +135 -0
- package/scripts/dgraph-test-db.sh +144 -0
- package/scripts/meadow-test-cleanup.sh +5 -1
- package/scripts/mongodb-test-db.sh +98 -0
- package/scripts/postgresql-test-db.sh +124 -0
- package/scripts/solr-test-db.sh +135 -0
- package/source/Meadow.js +5 -0
- package/source/providers/Meadow-Provider-DGraph.js +679 -0
- package/source/providers/Meadow-Provider-MongoDB.js +527 -0
- package/source/providers/Meadow-Provider-PostgreSQL.js +361 -0
- package/source/providers/Meadow-Provider-RocksDB.js +1300 -0
- package/source/providers/Meadow-Provider-Solr.js +726 -0
- package/test/Meadow-Provider-DGraph_tests.js +741 -0
- package/test/Meadow-Provider-MongoDB_tests.js +661 -0
- package/test/Meadow-Provider-PostgreSQL_tests.js +787 -0
- package/test/Meadow-Provider-RocksDB_tests.js +887 -0
- package/test/Meadow-Provider-Solr_tests.js +679 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# doUndelete
|
|
2
|
+
|
|
3
|
+
Restore a soft-deleted record by setting its `Deleted` flag back to `0`.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
meadow.doUndelete(pQuery, fCallBack)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Parameters
|
|
12
|
+
|
|
13
|
+
| Name | Type | Description |
|
|
14
|
+
|------|------|-------------|
|
|
15
|
+
| `pQuery` | `Object` | A FoxHound query object with filters identifying the record(s) to restore |
|
|
16
|
+
| `fCallBack` | `Function` | Callback invoked when the operation completes |
|
|
17
|
+
|
|
18
|
+
## Callback
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
function (pError, pQuery, pCount)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
| Name | Type | Description |
|
|
25
|
+
|------|------|-------------|
|
|
26
|
+
| `pError` | `string\|null` | Error message, or falsy on success |
|
|
27
|
+
| `pQuery` | `Object` | The FoxHound query used for the undelete operation |
|
|
28
|
+
| `pCount` | `number` | The number of affected records |
|
|
29
|
+
|
|
30
|
+
## Returns
|
|
31
|
+
|
|
32
|
+
Returns the Meadow instance for chaining.
|
|
33
|
+
|
|
34
|
+
## Description
|
|
35
|
+
|
|
36
|
+
`doUndelete` executes a single-step asynchronous waterfall:
|
|
37
|
+
|
|
38
|
+
1. **Undelete** -- If an `Undelete` raw query override is set via
|
|
39
|
+
`rawQueries.setQuery('Undelete', ...)`, it is used. Otherwise, the
|
|
40
|
+
provider's `Undelete` method executes the query, issuing
|
|
41
|
+
`UPDATE {Scope} SET Deleted=0 WHERE ...`.
|
|
42
|
+
|
|
43
|
+
The `DeleteDate` and `DeletingIDUser` columns are preserved as historical
|
|
44
|
+
records of the previous deletion. They are **not** cleared during an undelete
|
|
45
|
+
operation.
|
|
46
|
+
|
|
47
|
+
## Examples
|
|
48
|
+
|
|
49
|
+
### Undelete by primary key
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
var tmpQuery = meadow.query
|
|
53
|
+
.addFilter('IDBook', 42)
|
|
54
|
+
.setDisableDeleteTracking(true);
|
|
55
|
+
|
|
56
|
+
meadow.doUndelete(tmpQuery,
|
|
57
|
+
function (pError, pQuery, pCount)
|
|
58
|
+
{
|
|
59
|
+
if (pError)
|
|
60
|
+
{
|
|
61
|
+
console.error('Undelete failed:', pError);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
console.log('Restored', pCount, 'record(s)');
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Undelete with a custom raw query
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
meadow.rawQueries.setQuery('Undelete',
|
|
72
|
+
'UPDATE Book SET Deleted=0 WHERE IDBook = :IDBook AND DeletingIDUser = :IDUser');
|
|
73
|
+
|
|
74
|
+
var tmpQuery = meadow.query
|
|
75
|
+
.addFilter('IDBook', 42);
|
|
76
|
+
|
|
77
|
+
meadow.doUndelete(tmpQuery,
|
|
78
|
+
function (pError, pQuery, pCount)
|
|
79
|
+
{
|
|
80
|
+
console.log('Custom undelete affected', pCount, 'record(s)');
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Notes
|
|
85
|
+
|
|
86
|
+
- `doUndelete` only applies to schemas that use soft deletion (those with a
|
|
87
|
+
`Deleted` column). It has no effect on schemas configured for hard deletion.
|
|
88
|
+
|
|
89
|
+
- The `DeleteDate` and `DeletingIDUser` values remain on the record after
|
|
90
|
+
undelete. This preserves the audit history of when and by whom the record was
|
|
91
|
+
previously deleted.
|
|
92
|
+
|
|
93
|
+
- You may need to use `setDisableDeleteTracking(true)` on the query when
|
|
94
|
+
building filters that target soft-deleted records, since the default behavior
|
|
95
|
+
excludes records where `Deleted = 1`.
|
|
96
|
+
|
|
97
|
+
- The `Undelete` raw query override applies to this method. Set it via
|
|
98
|
+
`meadow.rawQueries.setQuery('Undelete', pQueryString)`.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# doUpdate
|
|
2
|
+
|
|
3
|
+
Update an existing record in the data source, read it back, and return the
|
|
4
|
+
marshalled result.
|
|
5
|
+
|
|
6
|
+
## Signature
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
meadow.doUpdate(pQuery, fCallBack)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Parameters
|
|
13
|
+
|
|
14
|
+
| Name | Type | Description |
|
|
15
|
+
|------|------|-------------|
|
|
16
|
+
| `pQuery` | `Object` | A FoxHound query object with a record containing the primary key and fields to update |
|
|
17
|
+
| `fCallBack` | `Function` | Callback invoked when the operation completes |
|
|
18
|
+
|
|
19
|
+
## Callback
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
function (pError, pUpdateQuery, pReadQuery, pRecord)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Name | Type | Description |
|
|
26
|
+
|------|------|-------------|
|
|
27
|
+
| `pError` | `string\|null` | Error message, or falsy on success |
|
|
28
|
+
| `pUpdateQuery` | `Object` | The FoxHound query used for the UPDATE operation |
|
|
29
|
+
| `pReadQuery` | `Object` | The FoxHound query used for the read-back operation |
|
|
30
|
+
| `pRecord` | `Object\|false` | The marshalled record after update, or `false` on failure |
|
|
31
|
+
|
|
32
|
+
## Returns
|
|
33
|
+
|
|
34
|
+
Returns the Meadow instance for chaining.
|
|
35
|
+
|
|
36
|
+
## Description
|
|
37
|
+
|
|
38
|
+
`doUpdate` executes a four-step asynchronous waterfall:
|
|
39
|
+
|
|
40
|
+
1. **Validate and prepare** -- Confirms that `pQuery.query.records` exists and
|
|
41
|
+
that the first record contains the `defaultIdentifier` column (e.g.
|
|
42
|
+
`IDBook`). The `IDUser` is set automatically from either `pQuery.userID` or
|
|
43
|
+
`meadow.userIdentifier` when not already present. Schema columns with type
|
|
44
|
+
`UpdateDate` and `UpdateIDUser` are reset to `false` so the provider can
|
|
45
|
+
auto-populate them (unless `disableAutoDateStamp` or `disableAutoUserStamp`
|
|
46
|
+
is set on the query). A filter is added for the primary key value, and a
|
|
47
|
+
safety check aborts if no filters are present.
|
|
48
|
+
|
|
49
|
+
2. **Update** -- The provider's `Update` method executes the update query.
|
|
50
|
+
|
|
51
|
+
3. **Read back** -- The updated record is read from the data source using the
|
|
52
|
+
same filters. If a `Read` raw query override is set, it is used.
|
|
53
|
+
|
|
54
|
+
4. **Marshal** -- The raw database row is converted to a plain JavaScript
|
|
55
|
+
object via `marshalRecordFromSourceToObject`.
|
|
56
|
+
|
|
57
|
+
## Examples
|
|
58
|
+
|
|
59
|
+
### Basic update
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
var tmpQuery = meadow.query
|
|
63
|
+
.addRecord({ IDBook: 42, Title: 'The Hobbit (Revised)' });
|
|
64
|
+
|
|
65
|
+
meadow.doUpdate(tmpQuery,
|
|
66
|
+
function (pError, pUpdateQuery, pReadQuery, pRecord)
|
|
67
|
+
{
|
|
68
|
+
if (pError)
|
|
69
|
+
{
|
|
70
|
+
console.error('Update failed:', pError);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
console.log('Updated title:', pRecord.Title);
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Partial update
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
// Only update the Author column; other columns are untouched
|
|
81
|
+
var tmpQuery = meadow.query
|
|
82
|
+
.addRecord({ IDBook: 42, Author: 'J.R.R. Tolkien' });
|
|
83
|
+
|
|
84
|
+
meadow.doUpdate(tmpQuery,
|
|
85
|
+
function (pError, pUpdateQuery, pReadQuery, pRecord)
|
|
86
|
+
{
|
|
87
|
+
console.log('Full record after update:', pRecord);
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Update with explicit user ID
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
var tmpQuery = meadow.query
|
|
95
|
+
.setIDUser(7)
|
|
96
|
+
.addRecord({ IDBook: 42, Title: 'Updated Title' });
|
|
97
|
+
|
|
98
|
+
meadow.doUpdate(tmpQuery,
|
|
99
|
+
function (pError, pUpdateQuery, pReadQuery, pRecord)
|
|
100
|
+
{
|
|
101
|
+
// ModifyingIDUser will be 7
|
|
102
|
+
console.log(pRecord.ModifyingIDUser);
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Notes
|
|
107
|
+
|
|
108
|
+
- The record **must** include the `defaultIdentifier` column (e.g. `IDBook`).
|
|
109
|
+
Without it, the callback receives `'Automated update missing default
|
|
110
|
+
identifier'`.
|
|
111
|
+
|
|
112
|
+
- **Safety check**: If no filters are present on the query after adding the
|
|
113
|
+
primary key filter, the update is aborted with
|
|
114
|
+
`'Automated update missing filters... aborting!'`. This prevents accidental
|
|
115
|
+
updates to every row in the table.
|
|
116
|
+
|
|
117
|
+
- `Update` raw query overrides are **not** supported. The source notes this
|
|
118
|
+
feature is deferred due to complexity. However, `Read` raw query overrides
|
|
119
|
+
**are** used during the read-back step.
|
|
120
|
+
|
|
121
|
+
- Schema columns with type `UpdateDate` are reset before the update so the
|
|
122
|
+
provider can populate them with the current timestamp. Columns with type
|
|
123
|
+
`UpdateIDUser` are reset so the provider can stamp the current user. This
|
|
124
|
+
automatic behavior can be disabled per-query with `disableAutoDateStamp` and
|
|
125
|
+
`disableAutoUserStamp`.
|
|
126
|
+
|
|
127
|
+
- Partial updates are supported. Only the columns present in the record
|
|
128
|
+
(besides the primary key) are modified. The read-back returns the complete
|
|
129
|
+
record.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# getRoleName
|
|
2
|
+
|
|
3
|
+
Get the human-readable role name for a numeric role index.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
meadow.getRoleName(pRoleIndex)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Parameters
|
|
12
|
+
|
|
13
|
+
| Name | Type | Description |
|
|
14
|
+
|------|------|-------------|
|
|
15
|
+
| `pRoleIndex` | `number` | The zero-based index of the role |
|
|
16
|
+
|
|
17
|
+
## Returns
|
|
18
|
+
|
|
19
|
+
| Type | Description |
|
|
20
|
+
|------|-------------|
|
|
21
|
+
| `string` | The role name corresponding to the index |
|
|
22
|
+
|
|
23
|
+
## Description
|
|
24
|
+
|
|
25
|
+
`getRoleName` maps a numeric role index to a human-readable role name string.
|
|
26
|
+
If the index is out of range (negative or beyond the array length), it returns
|
|
27
|
+
`'Unauthenticated'`.
|
|
28
|
+
|
|
29
|
+
## Default Role Names
|
|
30
|
+
|
|
31
|
+
| Index | Role Name |
|
|
32
|
+
|-------|-----------|
|
|
33
|
+
| 0 | `'Unauthenticated'` |
|
|
34
|
+
| 1 | `'User'` |
|
|
35
|
+
| 2 | `'Manager'` |
|
|
36
|
+
| 3 | `'Director'` |
|
|
37
|
+
| 4 | `'Executive'` |
|
|
38
|
+
| 5 | `'Administrator'` |
|
|
39
|
+
|
|
40
|
+
## Examples
|
|
41
|
+
|
|
42
|
+
### Get a role name
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
console.log(meadow.getRoleName(0)); // 'Unauthenticated'
|
|
46
|
+
console.log(meadow.getRoleName(1)); // 'User'
|
|
47
|
+
console.log(meadow.getRoleName(5)); // 'Administrator'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Out-of-range index
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
console.log(meadow.getRoleName(-1)); // 'Unauthenticated'
|
|
54
|
+
console.log(meadow.getRoleName(99)); // 'Unauthenticated'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Custom role names via Fable settings
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
var tmpFable = libFable.new({
|
|
61
|
+
MeadowRoleNames: [
|
|
62
|
+
'Anonymous',
|
|
63
|
+
'Reader',
|
|
64
|
+
'Editor',
|
|
65
|
+
'Admin',
|
|
66
|
+
'SuperAdmin'
|
|
67
|
+
]
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
var meadow = libMeadow.new(tmpFable, 'Book');
|
|
71
|
+
console.log(meadow.getRoleName(0)); // 'Anonymous'
|
|
72
|
+
console.log(meadow.getRoleName(3)); // 'Admin'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Notes
|
|
76
|
+
|
|
77
|
+
- The default role names can be overridden by providing an array as
|
|
78
|
+
`MeadowRoleNames` in the Fable settings. The array must be provided at
|
|
79
|
+
Meadow construction time.
|
|
80
|
+
|
|
81
|
+
- The role names are used by the authorizer system (set via `setAuthorizer`)
|
|
82
|
+
to map numeric user roles to permission sets.
|
|
83
|
+
|
|
84
|
+
- If `MeadowRoleNames` is not an array, the default six-role set is used.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# loadFromPackage / loadFromPackageObject
|
|
2
|
+
|
|
3
|
+
Load a complete Meadow configuration from a JSON package file or a JavaScript
|
|
4
|
+
object.
|
|
5
|
+
|
|
6
|
+
## Signatures
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
meadow.loadFromPackage(pPackage)
|
|
10
|
+
meadow.loadFromPackageObject(pPackage)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Parameters
|
|
14
|
+
|
|
15
|
+
### loadFromPackage
|
|
16
|
+
|
|
17
|
+
| Name | Type | Description |
|
|
18
|
+
|------|------|-------------|
|
|
19
|
+
| `pPackage` | `string` | File path to a JSON package (resolved via `require()`) |
|
|
20
|
+
|
|
21
|
+
### loadFromPackageObject
|
|
22
|
+
|
|
23
|
+
| Name | Type | Description |
|
|
24
|
+
|------|------|-------------|
|
|
25
|
+
| `pPackage` | `Object` | A JavaScript object containing the package definition |
|
|
26
|
+
|
|
27
|
+
## Returns
|
|
28
|
+
|
|
29
|
+
Returns a **new** Meadow instance configured from the package, or `false` on
|
|
30
|
+
error. This does **not** modify the calling instance.
|
|
31
|
+
|
|
32
|
+
## Description
|
|
33
|
+
|
|
34
|
+
These methods create a brand-new Meadow instance and configure it from a
|
|
35
|
+
package definition. The package can contain all of the following properties:
|
|
36
|
+
|
|
37
|
+
| Property | Type | Method Called |
|
|
38
|
+
|----------|------|--------------|
|
|
39
|
+
| `Scope` | `string` | `setScope()` |
|
|
40
|
+
| `Domain` | `string` | `setDomain()` |
|
|
41
|
+
| `DefaultIdentifier` | `string` | `setDefaultIdentifier()` |
|
|
42
|
+
| `Schema` | `Array` | `setSchema()` |
|
|
43
|
+
| `JsonSchema` | `Object` | `setJsonSchema()` |
|
|
44
|
+
| `DefaultObject` | `Object` | `setDefault()` |
|
|
45
|
+
| `Authorization` | `Object` | `setAuthorizer()` |
|
|
46
|
+
|
|
47
|
+
`loadFromPackage` uses `require()` to load the file, so relative paths are
|
|
48
|
+
resolved relative to the module. `loadFromPackageObject` takes the object
|
|
49
|
+
directly.
|
|
50
|
+
|
|
51
|
+
The new Meadow instance inherits the Fable context from the calling instance.
|
|
52
|
+
|
|
53
|
+
## Package File Format
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"Scope": "Book",
|
|
58
|
+
"Domain": "Library",
|
|
59
|
+
"DefaultIdentifier": "IDBook",
|
|
60
|
+
"Schema": [
|
|
61
|
+
{ "Column": "IDBook", "Type": "AutoIdentity" },
|
|
62
|
+
{ "Column": "GUIDBook", "Type": "AutoGUID" },
|
|
63
|
+
{ "Column": "Title", "Type": "String", "Size": "256" },
|
|
64
|
+
{ "Column": "Created", "Type": "CreateDate" },
|
|
65
|
+
{ "Column": "CreatingIDUser", "Type": "CreateIDUser" },
|
|
66
|
+
{ "Column": "Modified", "Type": "UpdateDate" },
|
|
67
|
+
{ "Column": "ModifyingIDUser", "Type": "UpdateIDUser" },
|
|
68
|
+
{ "Column": "Deleted", "Type": "Deleted" },
|
|
69
|
+
{ "Column": "DeletingIDUser", "Type": "DeleteIDUser" },
|
|
70
|
+
{ "Column": "DeleteDate", "Type": "DeleteDate" }
|
|
71
|
+
],
|
|
72
|
+
"JsonSchema": {
|
|
73
|
+
"title": "Book",
|
|
74
|
+
"type": "object",
|
|
75
|
+
"properties": {
|
|
76
|
+
"Title": { "type": "string" }
|
|
77
|
+
},
|
|
78
|
+
"required": ["Title"]
|
|
79
|
+
},
|
|
80
|
+
"DefaultObject": {
|
|
81
|
+
"IDBook": 0,
|
|
82
|
+
"GUIDBook": "",
|
|
83
|
+
"Title": ""
|
|
84
|
+
},
|
|
85
|
+
"Authorization": {
|
|
86
|
+
"User": {
|
|
87
|
+
"Create": "Allow",
|
|
88
|
+
"Read": "Allow",
|
|
89
|
+
"Update": "Allow",
|
|
90
|
+
"Delete": "Allow"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Examples
|
|
97
|
+
|
|
98
|
+
### Load from a file path
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
var tmpBookMeadow = libMeadow.new(tmpFable)
|
|
102
|
+
.loadFromPackage(__dirname + '/schemas/Book.json');
|
|
103
|
+
|
|
104
|
+
if (!tmpBookMeadow)
|
|
105
|
+
{
|
|
106
|
+
console.error('Failed to load package');
|
|
107
|
+
}
|
|
108
|
+
else
|
|
109
|
+
{
|
|
110
|
+
console.log(tmpBookMeadow.scope); // 'Book'
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Load from a JavaScript object
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
var tmpPackage = {
|
|
118
|
+
Scope: 'Author',
|
|
119
|
+
DefaultIdentifier: 'IDAuthor',
|
|
120
|
+
Schema: [
|
|
121
|
+
{ Column: 'IDAuthor', Type: 'AutoIdentity' },
|
|
122
|
+
{ Column: 'GUIDAuthor', Type: 'AutoGUID' },
|
|
123
|
+
{ Column: 'Name', Type: 'String', Size: '128' }
|
|
124
|
+
],
|
|
125
|
+
DefaultObject: {
|
|
126
|
+
IDAuthor: 0,
|
|
127
|
+
GUIDAuthor: '',
|
|
128
|
+
Name: ''
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
var tmpAuthorMeadow = libMeadow.new(tmpFable)
|
|
133
|
+
.loadFromPackageObject(tmpPackage);
|
|
134
|
+
|
|
135
|
+
console.log(tmpAuthorMeadow.scope); // 'Author'
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Notes
|
|
139
|
+
|
|
140
|
+
- Both methods return a **new** Meadow instance. They do not modify the
|
|
141
|
+
calling instance. Assign the return value to use the configured instance.
|
|
142
|
+
|
|
143
|
+
- `loadFromPackage` returns `false` if the `require()` call fails (file not
|
|
144
|
+
found, JSON parse error, etc.). An error is logged via the Fable logger.
|
|
145
|
+
|
|
146
|
+
- `loadFromPackageObject` logs a warning if the object does not have a `Scope`
|
|
147
|
+
property but still creates the new instance.
|
|
148
|
+
|
|
149
|
+
- All package properties are optional. Only properties present in the package
|
|
150
|
+
are applied to the new instance.
|
|
151
|
+
|
|
152
|
+
- The new instance inherits the Fable context (and therefore the provider
|
|
153
|
+
setting from `MeadowProvider` in Fable settings) from the calling instance.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# marshalRecordFromSourceToObject
|
|
2
|
+
|
|
3
|
+
Convert a raw database record into a plain JavaScript object using the schema
|
|
4
|
+
and default object template.
|
|
5
|
+
|
|
6
|
+
## Signature
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
meadow.marshalRecordFromSourceToObject(pRecord)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Parameters
|
|
13
|
+
|
|
14
|
+
| Name | Type | Description |
|
|
15
|
+
|------|------|-------------|
|
|
16
|
+
| `pRecord` | `Object` | A raw database record as returned by the provider |
|
|
17
|
+
|
|
18
|
+
## Returns
|
|
19
|
+
|
|
20
|
+
| Type | Description |
|
|
21
|
+
|------|-------------|
|
|
22
|
+
| `Object` | A plain JavaScript object with all schema columns populated |
|
|
23
|
+
|
|
24
|
+
## Description
|
|
25
|
+
|
|
26
|
+
`marshalRecordFromSourceToObject` performs a two-step conversion:
|
|
27
|
+
|
|
28
|
+
1. **Clone the default object** -- Creates a shallow copy of the default object
|
|
29
|
+
template (set via `setDefault`), ensuring all schema columns have initial
|
|
30
|
+
values.
|
|
31
|
+
|
|
32
|
+
2. **Overlay provider values** -- Calls the active provider's
|
|
33
|
+
`marshalRecordFromSourceToObject` method to map raw database values onto
|
|
34
|
+
the cloned object according to the column schema.
|
|
35
|
+
|
|
36
|
+
This guarantees a consistent object shape regardless of what the database
|
|
37
|
+
returned. Missing or null columns fall back to the default values.
|
|
38
|
+
|
|
39
|
+
## Examples
|
|
40
|
+
|
|
41
|
+
### Basic usage
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
// Assume a raw database row from the provider
|
|
45
|
+
var tmpRawRow = {
|
|
46
|
+
IDBook: 42,
|
|
47
|
+
GUIDBook: '0xABCDE-12345',
|
|
48
|
+
Title: 'Dune',
|
|
49
|
+
Author: 'Herbert',
|
|
50
|
+
PageCount: 412,
|
|
51
|
+
Created: '2024-01-15T10:30:00Z',
|
|
52
|
+
CreatingIDUser: 1,
|
|
53
|
+
Modified: null,
|
|
54
|
+
ModifyingIDUser: null,
|
|
55
|
+
Deleted: 0,
|
|
56
|
+
DeletingIDUser: 0,
|
|
57
|
+
DeleteDate: null
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
var tmpRecord = meadow.marshalRecordFromSourceToObject(tmpRawRow);
|
|
61
|
+
console.log(tmpRecord.Title); // 'Dune'
|
|
62
|
+
console.log(tmpRecord.Modified); // '' (from default, since DB returned null)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Used internally by CRUD methods
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
// You typically do not call this directly.
|
|
69
|
+
// It is called automatically by doCreate, doRead, doReads, and doUpdate
|
|
70
|
+
// when marshalling results back to the caller.
|
|
71
|
+
|
|
72
|
+
meadow.doRead(tmpQuery,
|
|
73
|
+
function (pError, pQuery, pRecord)
|
|
74
|
+
{
|
|
75
|
+
// pRecord has already been marshalled
|
|
76
|
+
console.log(pRecord);
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Notes
|
|
81
|
+
|
|
82
|
+
- This method is called internally by `doCreate`, `doRead`, `doReads`, and
|
|
83
|
+
`doUpdate`. Direct use is uncommon but available for custom scenarios.
|
|
84
|
+
|
|
85
|
+
- The returned object is a new plain object, not a reference to the default
|
|
86
|
+
object or the original database row.
|
|
87
|
+
|
|
88
|
+
- The provider's marshalling logic handles type-specific conversions (e.g.,
|
|
89
|
+
date formatting, numeric parsing) depending on the database backend.
|
|
90
|
+
|
|
91
|
+
- If `setDefault` has not been called, the base object is an empty `{}` and
|
|
92
|
+
only columns present in the database row will appear on the result.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# query (Property)
|
|
2
|
+
|
|
3
|
+
Access a fresh, cloned FoxHound query object pre-configured with the current
|
|
4
|
+
scope and schema.
|
|
5
|
+
|
|
6
|
+
## Signature
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
var tmpQuery = meadow.query;
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Returns
|
|
13
|
+
|
|
14
|
+
| Type | Description |
|
|
15
|
+
|------|-------------|
|
|
16
|
+
| `Object` | A cloned FoxHound query with scope and schema pre-set |
|
|
17
|
+
|
|
18
|
+
## Description
|
|
19
|
+
|
|
20
|
+
The `query` property returns a **new clone** of the internal FoxHound query
|
|
21
|
+
every time it is accessed. This ensures that each query operation gets an
|
|
22
|
+
independent query object with no shared mutable state.
|
|
23
|
+
|
|
24
|
+
The cloned query inherits:
|
|
25
|
+
|
|
26
|
+
- The current **scope** (table name)
|
|
27
|
+
- The current **schema** (column definitions)
|
|
28
|
+
- Any **filters**, **cap**, **begin**, and **data elements** from the base
|
|
29
|
+
query (these are cloned values, not references)
|
|
30
|
+
|
|
31
|
+
Because each access creates a fresh clone, it is safe to write:
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
var tmpQuery = meadow.query;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
without worrying about leakage between subsequent queries.
|
|
38
|
+
|
|
39
|
+
## Key Methods on the Returned Query
|
|
40
|
+
|
|
41
|
+
| Method | Description |
|
|
42
|
+
|--------|-------------|
|
|
43
|
+
| `addFilter(pColumn, pValue, pOperator, pConnector, pType)` | Add a WHERE filter |
|
|
44
|
+
| `addRecord(pRecord)` | Add a record for Create/Update operations |
|
|
45
|
+
| `setCap(pCap)` | Set the maximum number of records (LIMIT) |
|
|
46
|
+
| `setBegin(pBegin)` | Set the starting offset (OFFSET) |
|
|
47
|
+
| `addSort(pSort)` | Add a sort clause (e.g. `{ Column: 'Title', Direction: 'ASC' }`) |
|
|
48
|
+
| `setDataElements(pDataElements)` | Set which columns to return (SELECT list) |
|
|
49
|
+
| `setDistinct(pDistinct)` | Enable DISTINCT on the query |
|
|
50
|
+
| `setDisableDeleteTracking(pDisable)` | Include soft-deleted records when `true` |
|
|
51
|
+
| `setIDUser(pIDUser)` | Set the user ID on the query |
|
|
52
|
+
| `clone()` | Create another independent clone of this query |
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
### Basic query for a read
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
var tmpQuery = meadow.query
|
|
60
|
+
.addFilter('IDBook', 42);
|
|
61
|
+
|
|
62
|
+
meadow.doRead(tmpQuery,
|
|
63
|
+
function (pError, pQuery, pRecord)
|
|
64
|
+
{
|
|
65
|
+
console.log(pRecord);
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Query with pagination and sorting
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
var tmpQuery = meadow.query
|
|
73
|
+
.addFilter('Author', 'Tolkien')
|
|
74
|
+
.setCap(25)
|
|
75
|
+
.setBegin(0)
|
|
76
|
+
.addSort({ Column: 'Title', Direction: 'ASC' });
|
|
77
|
+
|
|
78
|
+
meadow.doReads(tmpQuery,
|
|
79
|
+
function (pError, pQuery, pRecords)
|
|
80
|
+
{
|
|
81
|
+
console.log(pRecords.length, 'results');
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Query with specific columns
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
var tmpQuery = meadow.query
|
|
89
|
+
.setDataElements(['IDBook', 'Title', 'Author']);
|
|
90
|
+
|
|
91
|
+
meadow.doReads(tmpQuery,
|
|
92
|
+
function (pError, pQuery, pRecords)
|
|
93
|
+
{
|
|
94
|
+
console.log(pRecords);
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Query for create with a record
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
var tmpQuery = meadow.query
|
|
102
|
+
.addRecord({ Title: 'Dune', Author: 'Herbert' });
|
|
103
|
+
|
|
104
|
+
meadow.doCreate(tmpQuery,
|
|
105
|
+
function (pError, pCreateQuery, pReadQuery, pRecord)
|
|
106
|
+
{
|
|
107
|
+
console.log('New ID:', pRecord.IDBook);
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Independent queries from the same meadow
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
var tmpQueryA = meadow.query.addFilter('IDBook', 1);
|
|
115
|
+
var tmpQueryB = meadow.query.addFilter('IDBook', 2);
|
|
116
|
+
|
|
117
|
+
// tmpQueryA and tmpQueryB are completely independent
|
|
118
|
+
// Modifying one does not affect the other
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Notes
|
|
122
|
+
|
|
123
|
+
- Every access to `meadow.query` creates a new clone. Do not access it in a
|
|
124
|
+
loop if you need the same query object -- assign it to a variable first.
|
|
125
|
+
|
|
126
|
+
- The query object is a FoxHound instance. See the FoxHound documentation for
|
|
127
|
+
the full query API.
|
|
128
|
+
|
|
129
|
+
- The schema is attached to the cloned query at `tmpQuery.query.schema`, which
|
|
130
|
+
providers use for query generation.
|
|
131
|
+
|
|
132
|
+
- Filters, cap, begin, and data elements survive cloning. Records do not
|
|
133
|
+
survive cloning by default.
|