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.
Files changed (59) hide show
  1. package/README.md +110 -141
  2. package/docs/README.md +34 -230
  3. package/docs/_cover.md +14 -0
  4. package/docs/_sidebar.md +44 -12
  5. package/docs/_topbar.md +5 -0
  6. package/docs/api/doCount.md +109 -0
  7. package/docs/api/doCreate.md +132 -0
  8. package/docs/api/doDelete.md +101 -0
  9. package/docs/api/doRead.md +122 -0
  10. package/docs/api/doReads.md +136 -0
  11. package/docs/api/doUndelete.md +98 -0
  12. package/docs/api/doUpdate.md +129 -0
  13. package/docs/api/getRoleName.md +84 -0
  14. package/docs/api/loadFromPackage.md +153 -0
  15. package/docs/api/marshalRecordFromSourceToObject.md +92 -0
  16. package/docs/api/query.md +133 -0
  17. package/docs/api/rawQueries.md +197 -0
  18. package/docs/api/reference.md +117 -0
  19. package/docs/api/setAuthorizer.md +103 -0
  20. package/docs/api/setDefault.md +90 -0
  21. package/docs/api/setDefaultIdentifier.md +84 -0
  22. package/docs/api/setDomain.md +56 -0
  23. package/docs/api/setIDUser.md +91 -0
  24. package/docs/api/setJsonSchema.md +92 -0
  25. package/docs/api/setProvider.md +87 -0
  26. package/docs/api/setSchema.md +107 -0
  27. package/docs/api/setScope.md +68 -0
  28. package/docs/api/validateObject.md +119 -0
  29. package/docs/architecture.md +316 -0
  30. package/docs/audit-tracking.md +226 -0
  31. package/docs/configuration.md +317 -0
  32. package/docs/providers/meadow-endpoints.md +306 -0
  33. package/docs/providers/mongodb.md +319 -0
  34. package/docs/providers/postgresql.md +312 -0
  35. package/docs/providers/rocksdb.md +297 -0
  36. package/docs/query-dsl.md +269 -0
  37. package/docs/quick-start.md +384 -0
  38. package/docs/raw-queries.md +193 -0
  39. package/docs/retold-catalog.json +61 -1
  40. package/docs/retold-keyword-index.json +15860 -4839
  41. package/docs/soft-deletes.md +224 -0
  42. package/package.json +36 -9
  43. package/scripts/bookstore-seed-postgresql.sql +135 -0
  44. package/scripts/dgraph-test-db.sh +144 -0
  45. package/scripts/meadow-test-cleanup.sh +5 -1
  46. package/scripts/mongodb-test-db.sh +98 -0
  47. package/scripts/postgresql-test-db.sh +124 -0
  48. package/scripts/solr-test-db.sh +135 -0
  49. package/source/Meadow.js +5 -0
  50. package/source/providers/Meadow-Provider-DGraph.js +679 -0
  51. package/source/providers/Meadow-Provider-MongoDB.js +527 -0
  52. package/source/providers/Meadow-Provider-PostgreSQL.js +361 -0
  53. package/source/providers/Meadow-Provider-RocksDB.js +1300 -0
  54. package/source/providers/Meadow-Provider-Solr.js +726 -0
  55. package/test/Meadow-Provider-DGraph_tests.js +741 -0
  56. package/test/Meadow-Provider-MongoDB_tests.js +661 -0
  57. package/test/Meadow-Provider-PostgreSQL_tests.js +787 -0
  58. package/test/Meadow-Provider-RocksDB_tests.js +887 -0
  59. 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.