meadow 2.0.23 → 2.0.27
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 +44 -13
- 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-MeadowEndpoints.js +1 -1
- 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-SQLiteBrowser-Headless_tests.js +657 -0
- package/test/Meadow-Provider-SQLiteBrowser_tests.js +895 -0
- package/test/Meadow-Provider-Solr_tests.js +679 -0
package/docs/_sidebar.md
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
- Getting Started
|
|
2
2
|
|
|
3
3
|
- [Introduction](/)
|
|
4
|
+
- [Quick Start](quick-start.md)
|
|
4
5
|
- [Architecture](architecture.md)
|
|
6
|
+
- [Configuration](configuration.md)
|
|
5
7
|
|
|
6
8
|
- Core Concepts
|
|
7
9
|
|
|
8
10
|
- [Schema](schema/README.md)
|
|
9
|
-
- [CRUD Operations](crud-operations.md)
|
|
10
11
|
- [Query DSL](query-dsl.md)
|
|
11
12
|
- [Raw Queries](raw-queries.md)
|
|
13
|
+
- [Audit Tracking](audit-tracking.md)
|
|
14
|
+
- [Soft Deletes](soft-deletes.md)
|
|
12
15
|
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
- [Schema Overview](schema/README.md)
|
|
16
|
-
|
|
17
|
-
- Query Operations
|
|
16
|
+
- CRUD Operations
|
|
18
17
|
|
|
19
|
-
- [
|
|
18
|
+
- [Overview](query/README.md)
|
|
20
19
|
- [Create](query/create.md)
|
|
21
20
|
- [Read](query/read.md)
|
|
22
21
|
- [Update](query/update.md)
|
|
@@ -25,14 +24,47 @@
|
|
|
25
24
|
|
|
26
25
|
- Providers
|
|
27
26
|
|
|
28
|
-
- [
|
|
27
|
+
- [Overview](providers/README.md)
|
|
29
28
|
- [MySQL](providers/mysql.md)
|
|
30
29
|
- [MSSQL](providers/mssql.md)
|
|
30
|
+
- [PostgreSQL](providers/postgresql.md)
|
|
31
31
|
- [SQLite](providers/sqlite.md)
|
|
32
|
+
- [MongoDB](providers/mongodb.md)
|
|
33
|
+
- [RocksDB](providers/rocksdb.md)
|
|
32
34
|
- [ALASQL](providers/alasql.md)
|
|
35
|
+
- [MeadowEndpoints](providers/meadow-endpoints.md)
|
|
33
36
|
|
|
34
|
-
-
|
|
37
|
+
- API Reference
|
|
35
38
|
|
|
36
|
-
- [
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
+
- [Overview](api/reference.md)
|
|
40
|
+
|
|
41
|
+
- CRUD Methods
|
|
42
|
+
|
|
43
|
+
- [doCreate()](api/doCreate.md)
|
|
44
|
+
- [doRead()](api/doRead.md)
|
|
45
|
+
- [doReads()](api/doReads.md)
|
|
46
|
+
- [doUpdate()](api/doUpdate.md)
|
|
47
|
+
- [doDelete()](api/doDelete.md)
|
|
48
|
+
- [doUndelete()](api/doUndelete.md)
|
|
49
|
+
- [doCount()](api/doCount.md)
|
|
50
|
+
|
|
51
|
+
- Configuration
|
|
52
|
+
|
|
53
|
+
- [setProvider()](api/setProvider.md)
|
|
54
|
+
- [setScope()](api/setScope.md)
|
|
55
|
+
- [setSchema()](api/setSchema.md)
|
|
56
|
+
- [setDefaultIdentifier()](api/setDefaultIdentifier.md)
|
|
57
|
+
- [setIDUser()](api/setIDUser.md)
|
|
58
|
+
- [setJsonSchema()](api/setJsonSchema.md)
|
|
59
|
+
- [setDefault()](api/setDefault.md)
|
|
60
|
+
- [setAuthorizer()](api/setAuthorizer.md)
|
|
61
|
+
- [setDomain()](api/setDomain.md)
|
|
62
|
+
- [loadFromPackage()](api/loadFromPackage.md)
|
|
63
|
+
|
|
64
|
+
- Utility
|
|
65
|
+
|
|
66
|
+
- [query (property)](api/query.md)
|
|
67
|
+
- [rawQueries](api/rawQueries.md)
|
|
68
|
+
- [validateObject()](api/validateObject.md)
|
|
69
|
+
- [marshalRecordFromSourceToObject()](api/marshalRecordFromSourceToObject.md)
|
|
70
|
+
- [getRoleName()](api/getRoleName.md)
|
package/docs/_topbar.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# doCount
|
|
2
|
+
|
|
3
|
+
Count records matching the query filters.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
meadow.doCount(pQuery, fCallBack)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Parameters
|
|
12
|
+
|
|
13
|
+
| Name | Type | Description |
|
|
14
|
+
|------|------|-------------|
|
|
15
|
+
| `pQuery` | `Object` | A FoxHound query object with optional filters |
|
|
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 count operation |
|
|
28
|
+
| `pCount` | `number\|false` | The integer count of matching records, or `false` on failure |
|
|
29
|
+
|
|
30
|
+
## Returns
|
|
31
|
+
|
|
32
|
+
Returns the Meadow instance for chaining.
|
|
33
|
+
|
|
34
|
+
## Description
|
|
35
|
+
|
|
36
|
+
`doCount` executes a two-step asynchronous waterfall:
|
|
37
|
+
|
|
38
|
+
1. **Count** -- If a `Count` raw query override is set via
|
|
39
|
+
`rawQueries.setQuery('Count', ...)`, it is used. Otherwise, the provider's
|
|
40
|
+
`Count` method executes the query.
|
|
41
|
+
|
|
42
|
+
2. **Validate and profile** -- The result is verified to be a number. If the
|
|
43
|
+
provider returned a non-numeric value, the callback receives
|
|
44
|
+
`'Count did not return valid results.'`. The elapsed time is checked against
|
|
45
|
+
the `QueryThresholdWarnTime` setting (default 200ms). If the query exceeded
|
|
46
|
+
the threshold, `logSlowQuery` emits a warning.
|
|
47
|
+
|
|
48
|
+
Soft-deleted records are excluded by default unless delete tracking is disabled
|
|
49
|
+
on the query.
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
|
|
53
|
+
### Count all records
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
var tmpQuery = meadow.query;
|
|
57
|
+
|
|
58
|
+
meadow.doCount(tmpQuery,
|
|
59
|
+
function (pError, pQuery, pCount)
|
|
60
|
+
{
|
|
61
|
+
if (pError)
|
|
62
|
+
{
|
|
63
|
+
console.error('Count error:', pError);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log('Total books:', pCount);
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Count with filters
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
var tmpQuery = meadow.query
|
|
74
|
+
.addFilter('Author', 'Tolkien');
|
|
75
|
+
|
|
76
|
+
meadow.doCount(tmpQuery,
|
|
77
|
+
function (pError, pQuery, pCount)
|
|
78
|
+
{
|
|
79
|
+
console.log('Books by Tolkien:', pCount);
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Count including soft-deleted records
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
var tmpQuery = meadow.query
|
|
87
|
+
.setDisableDeleteTracking(true);
|
|
88
|
+
|
|
89
|
+
meadow.doCount(tmpQuery,
|
|
90
|
+
function (pError, pQuery, pCount)
|
|
91
|
+
{
|
|
92
|
+
console.log('Total including deleted:', pCount);
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Notes
|
|
97
|
+
|
|
98
|
+
- The `Count` raw query override applies to this method. Set it via
|
|
99
|
+
`meadow.rawQueries.setQuery('Count', pQueryString)`.
|
|
100
|
+
|
|
101
|
+
- Slow query profiling measures elapsed wall time from the start of `doCount`
|
|
102
|
+
through provider completion. The threshold defaults to 200ms and can be
|
|
103
|
+
configured via the `QueryThresholdWarnTime` Fable setting.
|
|
104
|
+
|
|
105
|
+
- The result is always an integer. If the provider returns a non-number, the
|
|
106
|
+
callback receives an error and `pCount` is `false`.
|
|
107
|
+
|
|
108
|
+
- Soft-deleted records are excluded by default. Use
|
|
109
|
+
`setDisableDeleteTracking(true)` on the query to include them in the count.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# doCreate
|
|
2
|
+
|
|
3
|
+
Insert a new record into the data source, read it back, and return the
|
|
4
|
+
marshalled result.
|
|
5
|
+
|
|
6
|
+
## Signature
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
meadow.doCreate(pQuery, fCallBack)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Parameters
|
|
13
|
+
|
|
14
|
+
| Name | Type | Description |
|
|
15
|
+
|------|------|-------------|
|
|
16
|
+
| `pQuery` | `Object` | A FoxHound query object with at least one record added via `addRecord()` |
|
|
17
|
+
| `fCallBack` | `Function` | Callback invoked when the operation completes |
|
|
18
|
+
|
|
19
|
+
## Callback
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
function (pError, pCreateQuery, pReadQuery, pRecord)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Name | Type | Description |
|
|
26
|
+
|------|------|-------------|
|
|
27
|
+
| `pError` | `string\|null` | Error message, or falsy on success |
|
|
28
|
+
| `pCreateQuery` | `Object` | The FoxHound query used for the INSERT operation |
|
|
29
|
+
| `pReadQuery` | `Object` | The FoxHound query used for the read-back operation |
|
|
30
|
+
| `pRecord` | `Object\|false` | The marshalled record, or `false` on failure |
|
|
31
|
+
|
|
32
|
+
## Returns
|
|
33
|
+
|
|
34
|
+
Returns the Meadow instance for chaining.
|
|
35
|
+
|
|
36
|
+
## Description
|
|
37
|
+
|
|
38
|
+
`doCreate` executes a four-step asynchronous waterfall:
|
|
39
|
+
|
|
40
|
+
1. **GUID uniqueness check** -- If the record contains a GUID column value
|
|
41
|
+
(the `defaultGUIdentifier`, e.g. `GUIDBook`) that is at least 5 characters
|
|
42
|
+
long, Meadow reads the data source to confirm no existing record has that
|
|
43
|
+
GUID. If a duplicate is found, the callback receives an error.
|
|
44
|
+
|
|
45
|
+
2. **Insert** -- The record is merged with the default object template so that
|
|
46
|
+
all schema columns have values. The `IDUser` is set automatically from
|
|
47
|
+
either `pQuery.userID` or `meadow.userIdentifier` when not already present
|
|
48
|
+
on the query. The provider's `Create` method executes the insert.
|
|
49
|
+
|
|
50
|
+
3. **Read back** -- After a successful insert, the newly created record is read
|
|
51
|
+
from the data source using the returned primary key value. If a `Read` raw
|
|
52
|
+
query override is set, it is used for this step.
|
|
53
|
+
|
|
54
|
+
4. **Marshal** -- The raw database row is converted to a plain JavaScript
|
|
55
|
+
object via `marshalRecordFromSourceToObject`.
|
|
56
|
+
|
|
57
|
+
## Examples
|
|
58
|
+
|
|
59
|
+
### Basic create
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
var tmpQuery = meadow.query
|
|
63
|
+
.addRecord({ Title: 'The Hobbit', Author: 'Tolkien' });
|
|
64
|
+
|
|
65
|
+
meadow.doCreate(tmpQuery,
|
|
66
|
+
function (pError, pCreateQuery, pReadQuery, pRecord)
|
|
67
|
+
{
|
|
68
|
+
if (pError)
|
|
69
|
+
{
|
|
70
|
+
console.error('Create failed:', pError);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
console.log('New record ID:', pRecord.IDBook);
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Create with a specific GUID
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
var tmpQuery = meadow.query
|
|
81
|
+
.addRecord({
|
|
82
|
+
GUIDBook: '0x12345-abcde-67890',
|
|
83
|
+
Title: 'Dune'
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
meadow.doCreate(tmpQuery,
|
|
87
|
+
function (pError, pCreateQuery, pReadQuery, pRecord)
|
|
88
|
+
{
|
|
89
|
+
if (pError)
|
|
90
|
+
{
|
|
91
|
+
// Error if GUID already exists
|
|
92
|
+
console.error(pError);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
console.log('Created with GUID:', pRecord.GUIDBook);
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Create with explicit user ID on the query
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
var tmpQuery = meadow.query
|
|
103
|
+
.setIDUser(42)
|
|
104
|
+
.addRecord({ Title: 'Neuromancer' });
|
|
105
|
+
|
|
106
|
+
meadow.doCreate(tmpQuery,
|
|
107
|
+
function (pError, pCreateQuery, pReadQuery, pRecord)
|
|
108
|
+
{
|
|
109
|
+
// CreatingIDUser will be 42
|
|
110
|
+
console.log(pRecord);
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Notes
|
|
115
|
+
|
|
116
|
+
- The query **must** have a record added via `addRecord()` before calling
|
|
117
|
+
`doCreate`. If `pQuery.query.records` is falsy, the callback receives
|
|
118
|
+
`'No record submitted'`.
|
|
119
|
+
|
|
120
|
+
- GUID uniqueness is only checked when the GUID value is at least 5 characters
|
|
121
|
+
long. Shorter values or empty strings skip the check.
|
|
122
|
+
|
|
123
|
+
- The default object template (set via `setDefault`) is merged into the record
|
|
124
|
+
before insert, ensuring all schema columns have initial values.
|
|
125
|
+
|
|
126
|
+
- `Create` raw query overrides are **not** supported. The comment in the source
|
|
127
|
+
notes that create overrides are too complex. However, `Read` raw query
|
|
128
|
+
overrides **are** used during the read-back step.
|
|
129
|
+
|
|
130
|
+
- The `IDUser` resolution order is: `pQuery.query.IDUser` (if already set) >
|
|
131
|
+
`pQuery.userID` (if a non-negative integer) > `meadow.userIdentifier`
|
|
132
|
+
(fallback).
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# doDelete
|
|
2
|
+
|
|
3
|
+
Delete a record from the data source. Uses soft delete when the schema includes
|
|
4
|
+
a `Deleted` column, otherwise performs a hard delete.
|
|
5
|
+
|
|
6
|
+
## Signature
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
meadow.doDelete(pQuery, fCallBack)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Parameters
|
|
13
|
+
|
|
14
|
+
| Name | Type | Description |
|
|
15
|
+
|------|------|-------------|
|
|
16
|
+
| `pQuery` | `Object` | A FoxHound query object with filters identifying the record(s) to delete |
|
|
17
|
+
| `fCallBack` | `Function` | Callback invoked when the operation completes |
|
|
18
|
+
|
|
19
|
+
## Callback
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
function (pError, pQuery, pCount)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Name | Type | Description |
|
|
26
|
+
|------|------|-------------|
|
|
27
|
+
| `pError` | `string\|null` | Error message, or falsy on success |
|
|
28
|
+
| `pQuery` | `Object` | The FoxHound query used for the delete operation |
|
|
29
|
+
| `pCount` | `number` | The number of affected records |
|
|
30
|
+
|
|
31
|
+
## Returns
|
|
32
|
+
|
|
33
|
+
Returns the Meadow instance for chaining.
|
|
34
|
+
|
|
35
|
+
## Description
|
|
36
|
+
|
|
37
|
+
`doDelete` executes a single-step asynchronous waterfall:
|
|
38
|
+
|
|
39
|
+
1. **Delete** -- If a `Delete` raw query override is set via
|
|
40
|
+
`rawQueries.setQuery('Delete', ...)`, it is used. Otherwise, the provider's
|
|
41
|
+
`Delete` method executes the query. The provider determines the actual SQL
|
|
42
|
+
based on the schema:
|
|
43
|
+
|
|
44
|
+
- **Soft delete**: If the schema contains a column with type `Deleted`, the
|
|
45
|
+
provider issues `UPDATE {Scope} SET Deleted=1, DeleteDate=NOW(),
|
|
46
|
+
DeletingIDUser={IDUser} WHERE ...`.
|
|
47
|
+
- **Hard delete**: If no `Deleted` column exists, the provider issues
|
|
48
|
+
`DELETE FROM {Scope} WHERE ...`.
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
|
|
52
|
+
### Delete by primary key
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
var tmpQuery = meadow.query
|
|
56
|
+
.addFilter('IDBook', 42);
|
|
57
|
+
|
|
58
|
+
meadow.doDelete(tmpQuery,
|
|
59
|
+
function (pError, pQuery, pCount)
|
|
60
|
+
{
|
|
61
|
+
if (pError)
|
|
62
|
+
{
|
|
63
|
+
console.error('Delete failed:', pError);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log('Deleted', pCount, 'record(s)');
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Delete with a custom raw query
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
meadow.rawQueries.setQuery('Delete',
|
|
74
|
+
'UPDATE Book SET Deleted=1, DeleteDate=NOW() WHERE IDBook = :IDBook AND OwnerIDUser = :IDUser');
|
|
75
|
+
|
|
76
|
+
var tmpQuery = meadow.query
|
|
77
|
+
.addFilter('IDBook', 42);
|
|
78
|
+
|
|
79
|
+
meadow.doDelete(tmpQuery,
|
|
80
|
+
function (pError, pQuery, pCount)
|
|
81
|
+
{
|
|
82
|
+
console.log('Custom delete affected', pCount, 'record(s)');
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Notes
|
|
87
|
+
|
|
88
|
+
- Soft delete is automatic when the schema includes `{ Column: 'Deleted',
|
|
89
|
+
Type: 'Deleted' }`. No configuration is needed beyond the schema definition.
|
|
90
|
+
|
|
91
|
+
- After a soft delete, the record still exists in the database with
|
|
92
|
+
`Deleted = 1`. Subsequent `doRead` and `doReads` calls will exclude it by
|
|
93
|
+
default (unless `setDisableDeleteTracking(true)` is set on the query).
|
|
94
|
+
|
|
95
|
+
- Use [doUndelete](doUndelete.md) to restore a soft-deleted record.
|
|
96
|
+
|
|
97
|
+
- The `Delete` raw query override applies to this method. Set it via
|
|
98
|
+
`meadow.rawQueries.setQuery('Delete', pQueryString)`.
|
|
99
|
+
|
|
100
|
+
- Hard deletes are irreversible. Only schemas without a `Deleted` column
|
|
101
|
+
trigger hard deletes.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# doRead
|
|
2
|
+
|
|
3
|
+
Read a single record from the data source and return it as a marshalled plain
|
|
4
|
+
object.
|
|
5
|
+
|
|
6
|
+
## Signature
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
meadow.doRead(pQuery, fCallBack)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Parameters
|
|
13
|
+
|
|
14
|
+
| Name | Type | Description |
|
|
15
|
+
|------|------|-------------|
|
|
16
|
+
| `pQuery` | `Object` | A FoxHound query object with filters set to identify the target record |
|
|
17
|
+
| `fCallBack` | `Function` | Callback invoked when the operation completes |
|
|
18
|
+
|
|
19
|
+
## Callback
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
function (pError, pQuery, pRecord)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Name | Type | Description |
|
|
26
|
+
|------|------|-------------|
|
|
27
|
+
| `pError` | `string\|null` | Error message, or falsy on success |
|
|
28
|
+
| `pQuery` | `Object` | The FoxHound query used for the read operation |
|
|
29
|
+
| `pRecord` | `Object\|false` | The marshalled record, or `false` if no record was found |
|
|
30
|
+
|
|
31
|
+
## Returns
|
|
32
|
+
|
|
33
|
+
Returns the Meadow instance for chaining.
|
|
34
|
+
|
|
35
|
+
## Description
|
|
36
|
+
|
|
37
|
+
`doRead` executes a two-step asynchronous waterfall:
|
|
38
|
+
|
|
39
|
+
1. **Read** -- The provider's `Read` method executes the query. If a `Read`
|
|
40
|
+
raw query override is set via `rawQueries.setQuery('Read', ...)`, it is
|
|
41
|
+
used instead of the auto-generated query.
|
|
42
|
+
|
|
43
|
+
2. **Marshal** -- If at least one record is returned, the first row is
|
|
44
|
+
converted to a plain JavaScript object via `marshalRecordFromSourceToObject`.
|
|
45
|
+
If no rows match, `pRecord` is `false` (not an error).
|
|
46
|
+
|
|
47
|
+
Soft-deleted records (those with `Deleted = 1`) are excluded by default unless
|
|
48
|
+
delete tracking has been explicitly disabled on the query via
|
|
49
|
+
`setDisableDeleteTracking(true)`.
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
|
|
53
|
+
### Read by primary key
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
var tmpQuery = meadow.query
|
|
57
|
+
.addFilter('IDBook', 42);
|
|
58
|
+
|
|
59
|
+
meadow.doRead(tmpQuery,
|
|
60
|
+
function (pError, pQuery, pRecord)
|
|
61
|
+
{
|
|
62
|
+
if (pError)
|
|
63
|
+
{
|
|
64
|
+
console.error('Read error:', pError);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (!pRecord)
|
|
68
|
+
{
|
|
69
|
+
console.log('No record found');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
console.log('Title:', pRecord.Title);
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Read by GUID
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
var tmpQuery = meadow.query
|
|
80
|
+
.addFilter('GUIDBook', '0x12345-abcde-67890');
|
|
81
|
+
|
|
82
|
+
meadow.doRead(tmpQuery,
|
|
83
|
+
function (pError, pQuery, pRecord)
|
|
84
|
+
{
|
|
85
|
+
if (pRecord)
|
|
86
|
+
{
|
|
87
|
+
console.log('Found:', pRecord.Title);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Read including soft-deleted records
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
var tmpQuery = meadow.query
|
|
96
|
+
.addFilter('IDBook', 99)
|
|
97
|
+
.setDisableDeleteTracking(true);
|
|
98
|
+
|
|
99
|
+
meadow.doRead(tmpQuery,
|
|
100
|
+
function (pError, pQuery, pRecord)
|
|
101
|
+
{
|
|
102
|
+
if (pRecord)
|
|
103
|
+
{
|
|
104
|
+
console.log('Deleted?', pRecord.Deleted);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Notes
|
|
110
|
+
|
|
111
|
+
- When no record is found, `pRecord` is `false` and `pError` is `undefined`
|
|
112
|
+
(not an error condition). Always check for a falsy record.
|
|
113
|
+
|
|
114
|
+
- `doRead` returns only the **first** matching record. To read multiple records,
|
|
115
|
+
use [doReads](doReads.md).
|
|
116
|
+
|
|
117
|
+
- The `Read` raw query override applies to this method. Set it via
|
|
118
|
+
`meadow.rawQueries.setQuery('Read', pQueryString)`.
|
|
119
|
+
|
|
120
|
+
- The returned object is built from the default object template overlaid with
|
|
121
|
+
provider-marshalled values, so all schema columns are present even if the
|
|
122
|
+
database row has nulls.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# doReads
|
|
2
|
+
|
|
3
|
+
Read multiple records from the data source and return them as an array of
|
|
4
|
+
marshalled plain objects.
|
|
5
|
+
|
|
6
|
+
## Signature
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
meadow.doReads(pQuery, fCallBack)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Parameters
|
|
13
|
+
|
|
14
|
+
| Name | Type | Description |
|
|
15
|
+
|------|------|-------------|
|
|
16
|
+
| `pQuery` | `Object` | A FoxHound query object with filters, pagination, and sort options |
|
|
17
|
+
| `fCallBack` | `Function` | Callback invoked when the operation completes |
|
|
18
|
+
|
|
19
|
+
## Callback
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
function (pError, pQuery, pRecords)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Name | Type | Description |
|
|
26
|
+
|------|------|-------------|
|
|
27
|
+
| `pError` | `string\|null` | Error message, or falsy on success |
|
|
28
|
+
| `pQuery` | `Object` | The FoxHound query used for the read operation |
|
|
29
|
+
| `pRecords` | `Array` | Array of marshalled record objects (empty array if none found) |
|
|
30
|
+
|
|
31
|
+
## Returns
|
|
32
|
+
|
|
33
|
+
Returns the Meadow instance for chaining.
|
|
34
|
+
|
|
35
|
+
## Description
|
|
36
|
+
|
|
37
|
+
`doReads` executes a two-step asynchronous waterfall:
|
|
38
|
+
|
|
39
|
+
1. **Read** -- The provider's `Read` method executes the query. If a `Reads`
|
|
40
|
+
raw query override is set via `rawQueries.setQuery('Reads', ...)`, it is
|
|
41
|
+
used instead of the auto-generated query.
|
|
42
|
+
|
|
43
|
+
2. **Marshal and profile** -- Each returned row is converted to a plain
|
|
44
|
+
JavaScript object via `marshalRecordFromSourceToObject` and pushed into an
|
|
45
|
+
array. After the provider returns, the elapsed time is checked against the
|
|
46
|
+
`QueryThresholdWarnTime` setting (default 200ms). If the query exceeded the
|
|
47
|
+
threshold, `logSlowQuery` emits a warning.
|
|
48
|
+
|
|
49
|
+
Soft-deleted records are excluded by default unless delete tracking is disabled
|
|
50
|
+
on the query.
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
### Read all records (with default cap)
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
var tmpQuery = meadow.query;
|
|
58
|
+
|
|
59
|
+
meadow.doReads(tmpQuery,
|
|
60
|
+
function (pError, pQuery, pRecords)
|
|
61
|
+
{
|
|
62
|
+
if (pError)
|
|
63
|
+
{
|
|
64
|
+
console.error('Reads error:', pError);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
console.log('Found', pRecords.length, 'records');
|
|
68
|
+
pRecords.forEach(function (pRecord)
|
|
69
|
+
{
|
|
70
|
+
console.log('-', pRecord.Title);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Read with filters and pagination
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
var tmpQuery = meadow.query
|
|
79
|
+
.addFilter('Author', 'Tolkien')
|
|
80
|
+
.setCap(10)
|
|
81
|
+
.setBegin(0)
|
|
82
|
+
.addSort({ Column: 'Title', Direction: 'ASC' });
|
|
83
|
+
|
|
84
|
+
meadow.doReads(tmpQuery,
|
|
85
|
+
function (pError, pQuery, pRecords)
|
|
86
|
+
{
|
|
87
|
+
console.log('Page 1:', pRecords.length, 'results');
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Read with specific data elements
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
var tmpQuery = meadow.query
|
|
95
|
+
.setDataElements(['IDBook', 'Title', 'Author']);
|
|
96
|
+
|
|
97
|
+
meadow.doReads(tmpQuery,
|
|
98
|
+
function (pError, pQuery, pRecords)
|
|
99
|
+
{
|
|
100
|
+
// Each record will have only the requested columns
|
|
101
|
+
// (plus any columns derived from the default object)
|
|
102
|
+
console.log(pRecords);
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Read with custom slow query threshold
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
// In Fable settings:
|
|
110
|
+
// { QueryThresholdWarnTime: 500 }
|
|
111
|
+
|
|
112
|
+
var tmpQuery = meadow.query
|
|
113
|
+
.addFilter('Genre', 'Fantasy');
|
|
114
|
+
|
|
115
|
+
meadow.doReads(tmpQuery,
|
|
116
|
+
function (pError, pQuery, pRecords)
|
|
117
|
+
{
|
|
118
|
+
// Queries taking longer than 500ms will trigger a warning log
|
|
119
|
+
console.log(pRecords.length, 'records');
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Notes
|
|
124
|
+
|
|
125
|
+
- The `Reads` raw query override is **separate** from the `Read` override. Set
|
|
126
|
+
it via `meadow.rawQueries.setQuery('Reads', pQueryString)`.
|
|
127
|
+
|
|
128
|
+
- Slow query profiling measures elapsed wall time from the start of `doReads`
|
|
129
|
+
through provider completion. The threshold defaults to 200ms and can be
|
|
130
|
+
configured via the `QueryThresholdWarnTime` Fable setting.
|
|
131
|
+
|
|
132
|
+
- Each record in the result array is independently marshalled through the
|
|
133
|
+
default object template, so all schema columns are present on every record.
|
|
134
|
+
|
|
135
|
+
- An empty result set returns an empty array `[]`, not `false`. This differs
|
|
136
|
+
from `doRead` which returns `false` for no results.
|