foxhound 2.0.19 → 2.0.21

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 CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  > A fluent query generation DSL for Node.js and the browser
4
4
 
5
- FoxHound is a database query builder that generates dialect-specific SQL from a single chainable API. It keeps your application code database-agnostic while producing safe, parameterized queries for MySQL, Microsoft SQL Server, SQLite, and ALASQL.
5
+ FoxHound is a database query builder that generates dialect-specific SQL from a single chainable API. It keeps your application code database-agnostic while producing safe, parameterized queries for MySQL, PostgreSQL, Microsoft SQL Server, SQLite, and ALASQL.
6
6
 
7
7
  ## Features
8
8
 
9
9
  - **Chainable API** — every configuration method returns the query object for fluent composition
10
- - **Multiple Dialects** — generate SQL for MySQL, MSSQL, SQLite, ALASQL, or plain English from the same code
10
+ - **Multiple Dialects** — generate SQL for MySQL, PostgreSQL, MSSQL, SQLite, ALASQL, or plain English from the same code
11
11
  - **Parameterized Queries** — user-supplied values are always bound as named parameters, preventing SQL injection
12
12
  - **Schema-Aware** — automatic management of identity columns, timestamps, user stamps, and soft-delete tracking
13
13
  - **Full CRUD + Count** — build CREATE, READ, UPDATE, DELETE, UNDELETE, and COUNT queries
@@ -70,6 +70,7 @@ Application Code
70
70
  | Dialect | Target | Identifier Quoting | Parameter Prefix | Pagination |
71
71
  |---------|--------|-------------------|-----------------|------------|
72
72
  | `MySQL` | MySQL / MariaDB | `` `backticks` `` | `:name` | `LIMIT offset, count` |
73
+ | `PostgreSQL` | PostgreSQL 9.5+ | `"double quotes"` | `:name` | `LIMIT count OFFSET offset` |
73
74
  | `MSSQL` | Microsoft SQL Server | `[brackets]` | `@name` | `OFFSET/FETCH` |
74
75
  | `SQLite` | SQLite 3 | `` `backticks` `` | `:name` | `LIMIT count OFFSET offset` |
75
76
  | `ALASQL` | ALASQL (in-memory) | `` `backticks` `` | `:name` | `LIMIT count FETCH offset` |
package/docs/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # FoxHound
2
2
 
3
+ > A fluent query generation DSL for Node.js and the browser
4
+
3
5
  FoxHound is a fluent query generation DSL for Node.js and the browser. It produces dialect-specific SQL (or other query formats) from a single chainable API, keeping your application code database-agnostic while generating safe, parameterized queries.
4
6
 
5
7
  ## Features
6
8
 
7
9
  - **Chainable API** — every configuration method returns the query object, so you can compose queries in a single expression
8
- - **Multiple Dialects** — generate SQL for MySQL, Microsoft SQL Server, SQLite, ALASQL, or plain English, all from the same code
10
+ - **Multiple Dialects** — generate SQL for MySQL, PostgreSQL, Microsoft SQL Server, SQLite, ALASQL, or plain English, all from the same code
9
11
  - **Parameterized Queries** — user-supplied values are always bound as named parameters, preventing SQL injection
10
12
  - **Schema-Aware** — when a schema is provided, FoxHound automatically manages identity columns, timestamps, user stamps, and soft-delete tracking
11
13
  - **Full CRUD + Count** — build CREATE, READ, UPDATE, DELETE, UNDELETE, and COUNT queries
@@ -22,30 +24,49 @@ $ npm install foxhound
22
24
 
23
25
  ```javascript
24
26
  var libFable = require('fable');
25
- var _Fable = new libFable({});
26
-
27
- var tmpQuery = _Fable.Utility.waterfall.FoxHound;
28
- // Or create a new query directly:
29
27
  var libFoxHound = require('foxhound');
28
+
29
+ var _Fable = new libFable({});
30
30
  var tmpQuery = libFoxHound.new(_Fable);
31
31
 
32
- tmpQuery.setScope('Users')
33
- .setCap(20)
34
- .setDialect('MySQL')
35
- .buildReadQuery();
32
+ tmpQuery
33
+ .setScope('Books')
34
+ .setDataElements(['Title', 'Author', 'PublishedYear'])
35
+ .addFilter('Genre', 'Science Fiction')
36
+ .addSort({Column: 'PublishedYear', Direction: 'Descending'})
37
+ .setCap(25)
38
+ .setDialect('MySQL')
39
+ .buildReadQuery();
36
40
 
37
41
  console.log(tmpQuery.query.body);
38
- // => SELECT `Users`.* FROM `Users` LIMIT 20;
42
+ // => SELECT `Title`, `Author`, `PublishedYear` FROM `Books`
43
+ // WHERE `Books`.`Genre` = :Genre_w0 ORDER BY PublishedYear DESC LIMIT 25;
44
+
45
+ console.log(tmpQuery.query.parameters);
46
+ // => { Genre_w0: 'Science Fiction' }
39
47
  ```
40
48
 
41
49
  ## How It Works
42
50
 
43
51
  1. **Create a Query** — instantiate via `foxhound.new(fable)` or through a Fable service
44
52
  2. **Configure** — chain methods to set scope (table), fields, filters, sorts, joins, and pagination
45
- 3. **Set a Dialect** — call `.setDialect('MySQL')` (or MSSQL, SQLite, ALASQL, English)
53
+ 3. **Set a Dialect** — call `.setDialect('MySQL')` (or PostgreSQL, MSSQL, SQLite, ALASQL, English)
46
54
  4. **Build** — call a build method such as `.buildReadQuery()` to generate the SQL
47
55
  5. **Execute** — read the generated SQL from `.query.body` and bound parameters from `.query.parameters`
48
56
 
57
+ ## Documentation
58
+
59
+ - [Quickstart](quickstart.md) — get up and running in five minutes
60
+ - [Architecture](architecture.md) — understand FoxHound's internal design
61
+ - [Filters](filters.md) — filter operators and logical grouping
62
+ - [Sorting](sorting.md) — ORDER BY clause generation
63
+ - [Joins](joins.md) — multi-table queries
64
+ - [Pagination](pagination.md) — LIMIT/OFFSET across dialects
65
+ - [Schema Integration](schema.md) — automatic column management
66
+ - [Dialects](dialects/README.md) — dialect-specific features and differences
67
+ - [API Reference](api/README.md) — complete function reference with code examples
68
+ - [Query Overrides](query-overrides.md) — custom SQL templates
69
+
49
70
  ## Related Packages
50
71
 
51
72
  | Package | Purpose |
package/docs/_cover.md CHANGED
@@ -5,7 +5,8 @@
5
5
  - Chainable API that generates dialect-specific SQL
6
6
  - Parameterized queries for safe, injection-free operation
7
7
  - Schema-aware with automatic identity, timestamp, and soft-delete management
8
- - Multiple dialects: MySQL, MSSQL, SQLite, ALASQL, and more
8
+ - Multiple dialects: MySQL, PostgreSQL, MSSQL, SQLite, ALASQL, and more
9
9
 
10
+ [Get Started](quickstart.md)
11
+ [API Reference](api/README.md)
10
12
  [GitHub](https://github.com/stevenvelozo/foxhound)
11
- [Get Started](#foxhound)
package/docs/_sidebar.md CHANGED
@@ -1,6 +1,7 @@
1
1
  - Getting Started
2
2
 
3
- - [Introduction](/)
3
+ - [Introduction](README.md)
4
+ - [Quickstart](quickstart.md)
4
5
  - [Architecture](architecture.md)
5
6
 
6
7
  - Query Building
@@ -23,10 +24,29 @@
23
24
 
24
25
  - [Dialects Overview](dialects/README.md)
25
26
  - [MySQL](dialects/mysql.md)
27
+ - [PostgreSQL](dialects/postgresql.md)
26
28
  - [MSSQL](dialects/mssql.md)
27
29
  - [SQLite](dialects/sqlite.md)
28
30
  - [ALASQL](dialects/alasql.md)
29
31
 
32
+ - API Reference
33
+
34
+ - [API Overview](api/README.md)
35
+ - [setScope](api/setScope.md)
36
+ - [setDialect](api/setDialect.md)
37
+ - [setDataElements](api/setDataElements.md)
38
+ - [addFilter / setFilter](api/addFilter.md)
39
+ - [addSort / setSort](api/addSort.md)
40
+ - [addJoin / setJoin](api/addJoin.md)
41
+ - [setCap / setBegin](api/setCap.md)
42
+ - [addRecord](api/addRecord.md)
43
+ - [setIDUser](api/setIDUser.md)
44
+ - [setDistinct](api/setDistinct.md)
45
+ - [Build Methods](api/buildQuery.md)
46
+ - [clone / reset](api/clone.md)
47
+ - [Behavior Flags](api/behaviorFlags.md)
48
+ - [Query Overrides](api/queryOverrides.md)
49
+
30
50
  - Advanced
31
51
 
32
52
  - [Schema Integration](schema.md)
@@ -0,0 +1,7 @@
1
+ # FoxHound
2
+
3
+ - [Introduction](README.md)
4
+ - [Quickstart](quickstart.md)
5
+ - [API Reference](api/README.md)
6
+ - [GitHub](https://github.com/stevenvelozo/foxhound)
7
+ - [npm](https://www.npmjs.com/package/foxhound)
@@ -0,0 +1,73 @@
1
+ # API Reference
2
+
3
+ Complete reference for every public method and property in FoxHound.
4
+
5
+ ## Creating a Query
6
+
7
+ ```javascript
8
+ var libFable = require('fable');
9
+ var libFoxHound = require('foxhound');
10
+
11
+ var _Fable = new libFable({});
12
+ var tmpQuery = libFoxHound.new(_Fable);
13
+ ```
14
+
15
+ ## Method Categories
16
+
17
+ ### Configuration
18
+
19
+ These methods configure the query and return `this` for chaining.
20
+
21
+ | Method | Purpose |
22
+ |--------|---------|
23
+ | [setScope(pScope)](api/setScope.md) | Set the target table or collection |
24
+ | [setDialect(pDialectName)](api/setDialect.md) | Set the SQL dialect for output |
25
+ | [setDataElements(pDataElements)](api/setDataElements.md) | Set which columns to select |
26
+ | [setDistinct(pDistinct)](api/setDistinct.md) | Enable DISTINCT results |
27
+ | [addFilter / setFilter](api/addFilter.md) | Add or set WHERE clause conditions |
28
+ | [addSort / setSort](api/addSort.md) | Add or set ORDER BY expressions |
29
+ | [addJoin / setJoin](api/addJoin.md) | Add or set JOIN expressions |
30
+ | [setCap / setBegin](api/setCap.md) | Set pagination (LIMIT / OFFSET) |
31
+ | [addRecord(pRecord)](api/addRecord.md) | Add a record for INSERT or UPDATE |
32
+ | [setIDUser(pIDUser)](api/setIDUser.md) | Set the user ID for audit columns |
33
+ | [Behavior Flags](api/behaviorFlags.md) | Disable auto-identity, timestamps, user stamps, delete tracking |
34
+
35
+ ### Query Building
36
+
37
+ | Method | Purpose |
38
+ |--------|---------|
39
+ | [Build Methods](api/buildQuery.md) | buildCreateQuery, buildReadQuery, buildUpdateQuery, buildDeleteQuery, buildUndeleteQuery, buildCountQuery |
40
+
41
+ ### Utility
42
+
43
+ | Method | Purpose |
44
+ |--------|---------|
45
+ | [clone / resetParameters / mergeParameters](api/clone.md) | Copy, reset, or merge query state |
46
+ | [Query Overrides](api/queryOverrides.md) | Custom SQL templates for Read and Count |
47
+
48
+ ## Properties
49
+
50
+ | Property | Type | Access | Description |
51
+ |----------|------|--------|-------------|
52
+ | `query` | Object | get/set | The generated query (`body`, `schema`, `records`, `parameters`) |
53
+ | `result` | Object | get/set | Execution results (`executed`, `value`, `error`) |
54
+ | `parameters` | Object | get/set | Full parameters state |
55
+ | `dialect` | Object | get | Current dialect object |
56
+ | `uuid` | String | get | Unique identifier for this query |
57
+ | `logLevel` | Integer | get | Current log level |
58
+ | `indexHints` | Array | get/set | Index hints for the database engine |
59
+
60
+ ## Chaining
61
+
62
+ All configuration methods return `this`, enabling fluent composition:
63
+
64
+ ```javascript
65
+ tmpQuery
66
+ .setScope('Books')
67
+ .setDataElements(['Title', 'Author'])
68
+ .addFilter('Genre', 'Fantasy')
69
+ .addSort('Title')
70
+ .setCap(25)
71
+ .setDialect('PostgreSQL')
72
+ .buildReadQuery();
73
+ ```
@@ -0,0 +1,170 @@
1
+ # addFilter / setFilter
2
+
3
+ Add or replace filter conditions for the WHERE clause.
4
+
5
+ ## addFilter
6
+
7
+ Add a single filter expression to the existing filter array.
8
+
9
+ ### Signature
10
+
11
+ ```javascript
12
+ tmpQuery.addFilter(pColumn, pValue, pOperator, pConnector, pParameter)
13
+ ```
14
+
15
+ ### Parameters
16
+
17
+ | Parameter | Type | Default | Description |
18
+ |-----------|------|---------|-------------|
19
+ | `pColumn` | String | *(required)* | Column name |
20
+ | `pValue` | Any | *(required)* | Value to compare against |
21
+ | `pOperator` | String | `'='` | Comparison operator |
22
+ | `pConnector` | String | `'AND'` | Logical connector (`AND`, `OR`, `NONE`) |
23
+ | `pParameter` | String | `pColumn` | Parameter name for bound values |
24
+
25
+ ### Returns
26
+
27
+ Returns `this` for chaining.
28
+
29
+ ### Examples
30
+
31
+ #### Simple equality filter
32
+
33
+ ```javascript
34
+ tmpQuery.addFilter('Genre', 'Science Fiction');
35
+ // WHERE Genre = :Genre_w0
36
+ ```
37
+
38
+ #### Greater than
39
+
40
+ ```javascript
41
+ tmpQuery.addFilter('PublishedYear', 2000, '>');
42
+ // WHERE PublishedYear > :PublishedYear_w0
43
+ ```
44
+
45
+ #### OR connector
46
+
47
+ ```javascript
48
+ tmpQuery
49
+ .addFilter('Genre', 'Science Fiction')
50
+ .addFilter('Genre', 'Fantasy', '=', 'OR');
51
+ // WHERE Genre = :Genre_w0 OR Genre = :Genre_w1
52
+ ```
53
+
54
+ #### LIKE operator
55
+
56
+ ```javascript
57
+ tmpQuery.addFilter('Title', '%Dune%', 'LIKE');
58
+ // WHERE Title LIKE :Title_w0
59
+ ```
60
+
61
+ #### IN operator
62
+
63
+ ```javascript
64
+ tmpQuery.addFilter('IDOffice', [10, 11, 15, 18], 'IN');
65
+ // WHERE IDOffice IN ( :IDOffice_w0 )
66
+ ```
67
+
68
+ #### NOT IN operator
69
+
70
+ ```javascript
71
+ tmpQuery.addFilter('Status', ['Deleted', 'Archived'], 'NOT IN');
72
+ // WHERE Status NOT IN ( :Status_w0 )
73
+ ```
74
+
75
+ #### IS NULL / IS NOT NULL
76
+
77
+ ```javascript
78
+ tmpQuery.addFilter('DeleteDate', '', 'IS NULL');
79
+ // WHERE DeleteDate IS NULL
80
+
81
+ tmpQuery.addFilter('Title', '', 'IS NOT NULL');
82
+ // WHERE Title IS NOT NULL
83
+ ```
84
+
85
+ #### Grouped conditions with parentheses
86
+
87
+ ```javascript
88
+ tmpQuery
89
+ .addFilter('', '', '(')
90
+ .addFilter('Genre', 'Science Fiction')
91
+ .addFilter('Genre', 'Fantasy', '=', 'OR')
92
+ .addFilter('', '', ')')
93
+ .addFilter('PublishedYear', 2000, '>');
94
+ // WHERE ( Genre = :Genre_w1 OR Genre = :Genre_w2 )
95
+ // AND PublishedYear > :PublishedYear_w4
96
+ ```
97
+
98
+ #### Custom parameter name
99
+
100
+ ```javascript
101
+ tmpQuery.addFilter('Books.Genre', 'Fantasy', '=', 'AND', 'BookGenre');
102
+ // WHERE Books.Genre = :BookGenre_w0
103
+ ```
104
+
105
+ ## setFilter
106
+
107
+ Replace the entire filter array.
108
+
109
+ ### Signature
110
+
111
+ ```javascript
112
+ tmpQuery.setFilter(pFilter)
113
+ ```
114
+
115
+ ### Parameters
116
+
117
+ | Parameter | Type | Description |
118
+ |-----------|------|-------------|
119
+ | `pFilter` | Object or Array | Filter expression(s) |
120
+
121
+ ### Examples
122
+
123
+ #### Single filter object
124
+
125
+ ```javascript
126
+ tmpQuery.setFilter({
127
+ Column: 'Genre',
128
+ Operator: '=',
129
+ Value: 'Fantasy',
130
+ Connector: 'AND',
131
+ Parameter: 'Genre'
132
+ });
133
+ ```
134
+
135
+ #### Multiple filters
136
+
137
+ ```javascript
138
+ tmpQuery.setFilter([
139
+ {Column: 'Genre', Operator: '=', Value: 'Fantasy', Connector: 'AND', Parameter: 'Genre'},
140
+ {Column: 'PublishedYear', Operator: '>', Value: 2000, Connector: 'AND', Parameter: 'PublishedYear'}
141
+ ]);
142
+ ```
143
+
144
+ ## Filter Object Structure
145
+
146
+ | Property | Type | Description |
147
+ |----------|------|-------------|
148
+ | `Column` | String | Column name to filter on |
149
+ | `Operator` | String | Comparison operator |
150
+ | `Value` | Any | Value to compare against |
151
+ | `Connector` | String | Logical connector: `AND`, `OR`, or `NONE` |
152
+ | `Parameter` | String | Named parameter key |
153
+
154
+ ## Supported Operators
155
+
156
+ | Operator | SQL | Description |
157
+ |----------|-----|-------------|
158
+ | `'='` | `=` | Equals (default) |
159
+ | `'!='` | `!=` | Not equals |
160
+ | `'>'` | `>` | Greater than |
161
+ | `'>='` | `>=` | Greater than or equal |
162
+ | `'<'` | `<` | Less than |
163
+ | `'<='` | `<=` | Less than or equal |
164
+ | `'LIKE'` | `LIKE` | Pattern match |
165
+ | `'IN'` | `IN (...)` | Value in set |
166
+ | `'NOT IN'` | `NOT IN (...)` | Value not in set |
167
+ | `'IS NULL'` | `IS NULL` | Null check |
168
+ | `'IS NOT NULL'` | `IS NOT NULL` | Not-null check |
169
+ | `'('` | `(` | Open group |
170
+ | `')'` | `)` | Close group |
@@ -0,0 +1,128 @@
1
+ # addJoin / setJoin
2
+
3
+ Add or replace JOIN expressions for multi-table queries.
4
+
5
+ ## addJoin
6
+
7
+ Add a single join expression.
8
+
9
+ ### Signature
10
+
11
+ ```javascript
12
+ tmpQuery.addJoin(pTable, pFrom, pTo, pType)
13
+ ```
14
+
15
+ ### Parameters
16
+
17
+ | Parameter | Type | Default | Description |
18
+ |-----------|------|---------|-------------|
19
+ | `pTable` | String | *(required)* | Table to join |
20
+ | `pFrom` | String | *(required)* | Column on the join table (must start with `pTable`) |
21
+ | `pTo` | String | *(required)* | Column on the base table (must include a `.`) |
22
+ | `pType` | String | `'INNER JOIN'` | Join type |
23
+
24
+ ### Returns
25
+
26
+ Returns `this` for chaining.
27
+
28
+ ### Examples
29
+
30
+ #### Inner join (default)
31
+
32
+ ```javascript
33
+ tmpQuery
34
+ .setScope('Books')
35
+ .addJoin('Authors', 'Authors.IDAuthor', 'Books.IDAuthor')
36
+ .setDialect('MySQL')
37
+ .buildReadQuery();
38
+
39
+ // => SELECT `Books`.* FROM `Books`
40
+ // INNER JOIN Authors ON Authors.IDAuthor = Books.IDAuthor;
41
+ ```
42
+
43
+ #### Left join
44
+
45
+ ```javascript
46
+ tmpQuery.addJoin('Authors', 'Authors.IDAuthor', 'Books.IDAuthor', 'LEFT JOIN');
47
+
48
+ // => ... LEFT JOIN Authors ON Authors.IDAuthor = Books.IDAuthor ...
49
+ ```
50
+
51
+ #### Right join
52
+
53
+ ```javascript
54
+ tmpQuery.addJoin('Reviews', 'Reviews.IDBook', 'Books.IDBook', 'RIGHT JOIN');
55
+
56
+ // => ... RIGHT JOIN Reviews ON Reviews.IDBook = Books.IDBook ...
57
+ ```
58
+
59
+ #### Multiple joins
60
+
61
+ ```javascript
62
+ tmpQuery
63
+ .setScope('Books')
64
+ .addJoin('Authors', 'Authors.IDAuthor', 'Books.IDAuthor')
65
+ .addJoin('Publishers', 'Publishers.IDPublisher', 'Books.IDPublisher', 'LEFT JOIN')
66
+ .setDialect('MySQL')
67
+ .buildReadQuery();
68
+
69
+ // => SELECT `Books`.* FROM `Books`
70
+ // INNER JOIN Authors ON Authors.IDAuthor = Books.IDAuthor
71
+ // LEFT JOIN Publishers ON Publishers.IDPublisher = Books.IDPublisher;
72
+ ```
73
+
74
+ ## setJoin
75
+
76
+ Replace the entire join array.
77
+
78
+ ### Signature
79
+
80
+ ```javascript
81
+ tmpQuery.setJoin(pJoin)
82
+ ```
83
+
84
+ ### Parameters
85
+
86
+ | Parameter | Type | Description |
87
+ |-----------|------|-------------|
88
+ | `pJoin` | Object or Array | Join expression(s) |
89
+
90
+ ### Examples
91
+
92
+ #### Single join object
93
+
94
+ ```javascript
95
+ tmpQuery.setJoin({
96
+ Type: 'INNER JOIN',
97
+ Table: 'Authors',
98
+ From: 'Authors.IDAuthor',
99
+ To: 'Books.IDAuthor'
100
+ });
101
+ ```
102
+
103
+ #### Array of joins
104
+
105
+ ```javascript
106
+ tmpQuery.setJoin([
107
+ {Type: 'INNER JOIN', Table: 'Authors', From: 'Authors.IDAuthor', To: 'Books.IDAuthor'},
108
+ {Type: 'LEFT JOIN', Table: 'Publishers', From: 'Publishers.IDPublisher', To: 'Books.IDPublisher'}
109
+ ]);
110
+ ```
111
+
112
+ ## Join Object Structure
113
+
114
+ | Property | Type | Description |
115
+ |----------|------|-------------|
116
+ | `Type` | String | Join type (e.g. `'INNER JOIN'`, `'LEFT JOIN'`, `'RIGHT JOIN'`) |
117
+ | `Table` | String | Table to join |
118
+ | `From` | String | Column on the join table |
119
+ | `To` | String | Column on the base or another table |
120
+
121
+ ## Validation
122
+
123
+ FoxHound validates join parameters:
124
+
125
+ - `pTable` must be a string
126
+ - `pFrom` must start with the join table name
127
+ - `pTo` must include a dot (table-qualified column name)
128
+ - Invalid joins are logged as warnings and silently skipped
@@ -0,0 +1,108 @@
1
+ # addRecord
2
+
3
+ Add a record for CREATE or UPDATE operations.
4
+
5
+ ## Signature
6
+
7
+ ```javascript
8
+ tmpQuery.addRecord(pRecord)
9
+ ```
10
+
11
+ ## Parameters
12
+
13
+ | Parameter | Type | Required | Description |
14
+ |-----------|------|----------|-------------|
15
+ | `pRecord` | Object | Yes | Key-value pairs of column names and values |
16
+
17
+ ## Returns
18
+
19
+ Returns `this` for chaining.
20
+
21
+ ## Description
22
+
23
+ Adds a record object to the query's record list. The keys become column names and the values become parameterized values in the generated SQL.
24
+
25
+ For CREATE operations, the record defines the column-value pairs for the INSERT statement. For UPDATE operations, the record defines the SET clause (which columns to change and their new values).
26
+
27
+ Only the first record in the list is used for query generation in the current implementation.
28
+
29
+ Non-object values are silently ignored.
30
+
31
+ ## Examples
32
+
33
+ ### Insert a new record
34
+
35
+ ```javascript
36
+ tmpQuery
37
+ .setScope('Books')
38
+ .addRecord({Title: 'Dune', Author: 'Frank Herbert', PublishedYear: 1965})
39
+ .setDialect('MySQL')
40
+ .buildCreateQuery();
41
+
42
+ console.log(tmpQuery.query.body);
43
+ // => INSERT INTO `Books` ( Title, Author, PublishedYear)
44
+ // VALUES ( :Title_0, :Author_1, :PublishedYear_2);
45
+
46
+ console.log(tmpQuery.query.parameters);
47
+ // => { Title_0: 'Dune', Author_1: 'Frank Herbert', PublishedYear_2: 1965 }
48
+ ```
49
+
50
+ ### Update a record
51
+
52
+ ```javascript
53
+ tmpQuery
54
+ .setScope('Books')
55
+ .addFilter('IDBook', 42)
56
+ .addRecord({Title: 'Dune Messiah', PublishedYear: 1969})
57
+ .setDialect('MySQL')
58
+ .buildUpdateQuery();
59
+
60
+ console.log(tmpQuery.query.body);
61
+ // => UPDATE `Books` SET Title = :Title_0, PublishedYear = :PublishedYear_1
62
+ // WHERE IDBook = :IDBook_w0;
63
+ ```
64
+
65
+ ### With schema for automatic column management
66
+
67
+ ```javascript
68
+ tmpQuery
69
+ .setScope('Books')
70
+ .addRecord({
71
+ IDBook: null,
72
+ Title: 'Neuromancer',
73
+ Author: 'William Gibson',
74
+ CreateDate: null,
75
+ CreatingIDUser: null,
76
+ UpdateDate: null,
77
+ UpdatingIDUser: null,
78
+ Deleted: 0
79
+ });
80
+
81
+ tmpQuery.query.schema = [
82
+ {Column: 'IDBook', Type: 'AutoIdentity'},
83
+ {Column: 'Title', Type: 'String'},
84
+ {Column: 'Author', Type: 'String'},
85
+ {Column: 'CreateDate', Type: 'CreateDate'},
86
+ {Column: 'CreatingIDUser', Type: 'CreateIDUser'},
87
+ {Column: 'UpdateDate', Type: 'UpdateDate'},
88
+ {Column: 'UpdatingIDUser', Type: 'UpdateIDUser'},
89
+ {Column: 'Deleted', Type: 'Deleted'}
90
+ ];
91
+
92
+ tmpQuery.query.IDUser = 5;
93
+ tmpQuery.setDialect('MySQL').buildCreateQuery();
94
+
95
+ // IDBook => NULL (AutoIdentity)
96
+ // CreateDate => NOW(3) (auto timestamp)
97
+ // CreatingIDUser => 5 (auto user stamp)
98
+ ```
99
+
100
+ ### Empty record
101
+
102
+ ```javascript
103
+ // No-op: buildCreateQuery() and buildUpdateQuery() return false
104
+ tmpQuery.addRecord({});
105
+ tmpQuery.buildCreateQuery();
106
+ console.log(tmpQuery.query.body);
107
+ // => false
108
+ ```