foxhound 2.0.13 → 2.0.16

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.
@@ -0,0 +1,50 @@
1
+ # Contributing to Retold
2
+
3
+ We welcome contributions to Retold and its modules. This guide covers the expectations and process for contributing.
4
+
5
+ ## Code of Conduct
6
+
7
+ The Retold community values **empathy**, **equity**, **kindness**, and **thoughtfulness**. We expect all participants to treat each other with respect, assume good intent, and engage constructively. These values apply to all interactions: pull requests, issues, discussions, and code review.
8
+
9
+ ## How to Contribute
10
+
11
+ ### Pull Requests
12
+
13
+ Pull requests are the preferred method for contributing changes. To submit one:
14
+
15
+ 1. Fork the module repository you want to change
16
+ 2. Create a branch for your work
17
+ 3. Make your changes, following the code style of the module you are editing
18
+ 4. Ensure your changes have test coverage (see below)
19
+ 5. Open a pull request against the module's main branch
20
+
21
+ **Submitting a pull request does not guarantee it will be accepted.** Maintainers review contributions for fit, quality, and alignment with the project's direction. A PR may be declined, or you may be asked to revise it. This is normal and not a reflection on the quality of your effort.
22
+
23
+ ### Reporting Issues
24
+
25
+ If you find a bug or have a feature suggestion, open an issue on the relevant module's repository. Include enough detail to reproduce the problem or understand the proposal.
26
+
27
+ ## Test Coverage
28
+
29
+ Every commit must include test coverage for the changes it introduces. Retold modules use Mocha in TDD style. Before submitting:
30
+
31
+ - **Write tests** for any new functionality or bug fixes
32
+ - **Run the existing test suite** with `npm test` and confirm all tests pass
33
+ - **Check coverage** with `npm run coverage` if the module supports it
34
+
35
+ Pull requests that break existing tests or lack coverage for new code will not be merged.
36
+
37
+ ## Code Style
38
+
39
+ Follow the conventions of the module you are working in. The general Retold style is:
40
+
41
+ - **Tabs** for indentation, never spaces
42
+ - **Plain JavaScript** only (no TypeScript)
43
+ - **Allman-style braces** (opening brace on its own line)
44
+ - **Variable naming:** `pVariable` for parameters, `tmpVariable` for temporaries, `libSomething` for imports
45
+
46
+ When in doubt, match what the surrounding code does.
47
+
48
+ ## Repository Structure
49
+
50
+ Each module is its own git repository. The [retold](https://github.com/stevenvelozo/retold) repository tracks module organization but does not contain module source code. Direct your pull request to the specific module repository where your change belongs.
package/README.md CHANGED
@@ -1,65 +1,147 @@
1
1
  # FoxHound
2
2
 
3
- The FoxHound javascript query generator, for node.js and the browser.
4
-
5
-
6
- ### Getting Started
7
-
8
- $ npm install foxhound --save
9
-
10
- Then...
11
-
12
- var foxhound = require('foxhound');
13
- var my_awesome_query = foxhound.scope('Users').cap(20).generate().query.body;
14
- console.log(my_awesome_query);
3
+ > A fluent query generation DSL for Node.js and the browser
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.
6
+
7
+ ## Features
8
+
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
11
+ - **Parameterized Queries** — user-supplied values are always bound as named parameters, preventing SQL injection
12
+ - **Schema-Aware** automatic management of identity columns, timestamps, user stamps, and soft-delete tracking
13
+ - **Full CRUD + Count** — build CREATE, READ, UPDATE, DELETE, UNDELETE, and COUNT queries
14
+ - **Query Overrides** — underscore-style templates for custom SQL while retaining automatic parameter binding
15
+ - **Filtering & Sorting** — rich filter expressions with multiple operators, logical grouping, and multi-column sorting
16
+ - **Joins & Pagination** — INNER, LEFT, and custom joins plus dialect-aware LIMIT/OFFSET pagination
17
+ - **Fable Integration** — operates as a Fable service, inheriting configuration, logging, and UUID generation
18
+
19
+ ## Quick Start
20
+
21
+ ```javascript
22
+ const libFable = require('fable');
23
+ const libFoxHound = require('foxhound');
24
+
25
+ const _Fable = new libFable({});
26
+ const tmpQuery = libFoxHound.new(_Fable);
27
+
28
+ tmpQuery
29
+ .setScope('Books')
30
+ .setDataElements(['Title', 'Author', 'PublishedYear'])
31
+ .addFilter('Genre', 'Science Fiction')
32
+ .addSort({Column: 'PublishedYear', Direction: 'Descending'})
33
+ .setCap(25)
34
+ .setDialect('MySQL')
35
+ .buildReadQuery();
36
+
37
+ console.log(tmpQuery.query.body);
38
+ // => SELECT `Title`, `Author`, `PublishedYear` FROM `Books`
39
+ // WHERE `Books`.`Genre` = :Genre_w0 ORDER BY PublishedYear DESC LIMIT 25;
40
+
41
+ console.log(tmpQuery.query.parameters);
42
+ // => { Genre_w0: 'Science Fiction' }
43
+ ```
15
44
 
16
- The default query dialect is english, so, node should output:
45
+ ## Installation
17
46
 
18
- Please give me 20 of your Users. Thank you!
47
+ ```bash
48
+ npm install foxhound
49
+ ```
19
50
 
20
- This is not very useful for anything other than testing, so, we might want to change the dialect and try again:
51
+ ## How It Works
21
52
 
22
- var foxhound = require('foxhound');
23
- var my_awesome_query = foxhound.scope('Users').cap(20).setDialect('MySQL').generate().query.body;
24
- console.log(my_awesome_query);
53
+ FoxHound follows a configure-then-build pattern. You create a query instance, chain configuration methods to set the table, columns, filters, sorts, and dialect, then call a build method to generate the SQL.
25
54
 
26
- Which now will output:
55
+ ```
56
+ Application Code
57
+ └── FoxHound Query
58
+ ├── setScope('Books') → target table
59
+ ├── addFilter('Genre', '...') → WHERE clause
60
+ ├── addSort('Title') → ORDER BY clause
61
+ ├── setCap(25) → LIMIT clause
62
+ ├── setDialect('MySQL') → output format
63
+ └── buildReadQuery() → SQL generation
64
+ ├── query.body → SQL string
65
+ └── query.parameters → bound values
66
+ ```
27
67
 
28
- SELECT * FROM Users LIMIT 20;
68
+ ## Dialects
69
+
70
+ | Dialect | Target | Identifier Quoting | Parameter Prefix | Pagination |
71
+ |---------|--------|-------------------|-----------------|------------|
72
+ | `MySQL` | MySQL / MariaDB | `` `backticks` `` | `:name` | `LIMIT offset, count` |
73
+ | `MSSQL` | Microsoft SQL Server | `[brackets]` | `@name` | `OFFSET/FETCH` |
74
+ | `SQLite` | SQLite 3 | `` `backticks` `` | `:name` | `LIMIT count OFFSET offset` |
75
+ | `ALASQL` | ALASQL (in-memory) | `` `backticks` `` | `:name` | `LIMIT count FETCH offset` |
76
+ | `English` | Human-readable | none | none | prose |
77
+ | `MeadowEndpoints` | REST URLs | none | none | query string |
78
+
79
+ ## Schema Types
80
+
81
+ When a schema is attached, FoxHound automatically manages special columns:
82
+
83
+ | Type | Description |
84
+ |------|-------------|
85
+ | `AutoIdentity` | Auto-increment primary key — `NULL` on insert, skipped on update |
86
+ | `AutoGUID` | Automatically generated UUID on insert |
87
+ | `CreateDate` / `CreateIDUser` | Auto-populated on insert only |
88
+ | `UpdateDate` / `UpdateIDUser` | Auto-populated on insert and update |
89
+ | `DeleteDate` / `DeleteIDUser` | Auto-populated on soft delete |
90
+ | `Deleted` | Soft-delete flag — auto-filtered in reads |
91
+
92
+ ## Filter Operators
93
+
94
+ | Operator | SQL | Description |
95
+ |----------|-----|-------------|
96
+ | `=` | `=` | Equals (default) |
97
+ | `!=` | `!=` | Not equals |
98
+ | `>`, `>=`, `<`, `<=` | `>`, `>=`, `<`, `<=` | Comparison |
99
+ | `LIKE` | `LIKE` | Pattern match |
100
+ | `IN`, `NOT IN` | `IN (...)`, `NOT IN (...)` | Set membership |
101
+ | `IS NULL`, `IS NOT NULL` | `IS NULL`, `IS NOT NULL` | Null checks |
102
+ | `(`, `)` | `(`, `)` | Logical grouping |
103
+
104
+ ## Testing
105
+
106
+ ```bash
107
+ npm test
108
+ npm run coverage
109
+ ```
29
110
 
30
- ### Testing
111
+ ## Docker Development Environment
31
112
 
32
- $ npm test
33
- $ npm run coverage
113
+ 1. Build the image:
34
114
 
35
- ### Docker Development Environment
115
+ ```bash
116
+ npm run docker-dev-build
117
+ ```
36
118
 
119
+ 2. Run the container:
37
120
 
38
- 1. Run this command to build this image:
39
- ```
40
- docker build ./ -t retold/foxhound:local
121
+ ```bash
122
+ npm run docker-dev-run
41
123
  ```
42
124
 
43
- alternatively you can use npm to run this
125
+ 3. Open http://localhost:24238/ the password is "retold"
44
126
 
127
+ ## Documentation
45
128
 
46
- ```
47
- npm run docker-dev-build-image
48
- ```
129
+ Detailed documentation is available in the `docs/` folder and can be served locally:
49
130
 
50
- 2. Run this command to build the local container:
51
- ```
52
- docker run -it --name foxhound-dev -p 127.0.0.1:12346:8080 -v "$PWD/.config:/home/coder/.config" -v "$PWD:/home/coder/foxhound" -u "$(id -u):$(id -g)" -e "DOCKER_USER=$USER" retold/foxhound:local
131
+ ```bash
132
+ npx docsify-cli serve docs
53
133
  ```
54
134
 
55
- alternatively you can use npm to run this
135
+ ## Related Packages
56
136
 
57
- ```
58
- npm run docker-dev-run
59
- ```
137
+ - [meadow](https://github.com/stevenvelozo/meadow) - Data access and ORM
138
+ - [stricture](https://github.com/stevenvelozo/stricture) - Schema definition language
139
+ - [fable](https://github.com/stevenvelozo/fable) - Application services framework
140
+
141
+ ## License
60
142
 
61
- 3. Go to http://localhost:12346/ in a web browser
143
+ MIT
62
144
 
63
- 4. The password is "retold"
145
+ ## Contributing
64
146
 
65
- 5. Right now you (may) need to delete the `node_modules` folders and regenerate it for Linux.
147
+ Pull requests are welcome. For details on our code of conduct, contribution process, and testing requirements, see the [Retold Contributing Guide](https://github.com/stevenvelozo/retold/blob/main/docs/contributing.md).
package/docs/.nojekyll ADDED
@@ -0,0 +1 @@
1
+
package/docs/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # FoxHound
2
+
3
+ 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
+
5
+ ## Features
6
+
7
+ - **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
9
+ - **Parameterized Queries** — user-supplied values are always bound as named parameters, preventing SQL injection
10
+ - **Schema-Aware** — when a schema is provided, FoxHound automatically manages identity columns, timestamps, user stamps, and soft-delete tracking
11
+ - **Full CRUD + Count** — build CREATE, READ, UPDATE, DELETE, UNDELETE, and COUNT queries
12
+ - **Query Overrides** — supply an underscore-style template to customize query generation while still benefiting from automatic parameter binding
13
+ - **Filtering & Sorting** — rich filter expressions with multiple operators, logical grouping, and multi-column sorting
14
+ - **Joins & Pagination** — INNER, LEFT, and custom joins plus dialect-aware LIMIT/OFFSET pagination
15
+ - **Fable Integration** — operates as a Fable service, inheriting configuration, logging, and UUID generation
16
+
17
+ ## Quick Start
18
+
19
+ ```
20
+ $ npm install foxhound
21
+ ```
22
+
23
+ ```javascript
24
+ 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
+ var libFoxHound = require('foxhound');
30
+ var tmpQuery = libFoxHound.new(_Fable);
31
+
32
+ tmpQuery.setScope('Users')
33
+ .setCap(20)
34
+ .setDialect('MySQL')
35
+ .buildReadQuery();
36
+
37
+ console.log(tmpQuery.query.body);
38
+ // => SELECT `Users`.* FROM `Users` LIMIT 20;
39
+ ```
40
+
41
+ ## How It Works
42
+
43
+ 1. **Create a Query** — instantiate via `foxhound.new(fable)` or through a Fable service
44
+ 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)
46
+ 4. **Build** — call a build method such as `.buildReadQuery()` to generate the SQL
47
+ 5. **Execute** — read the generated SQL from `.query.body` and bound parameters from `.query.parameters`
48
+
49
+ ## Related Packages
50
+
51
+ | Package | Purpose |
52
+ |---------|---------|
53
+ | [fable](https://github.com/stevenvelozo/fable) | Core service framework (required dependency) |
54
+ | [meadow](https://github.com/stevenvelozo/meadow) | Data access layer that uses FoxHound for query generation |
55
+ | [stricture](https://github.com/stevenvelozo/stricture) | Schema definition tool that produces FoxHound-compatible schema arrays |
56
+ | [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) | REST endpoint generator built on Meadow + FoxHound |
57
+
58
+ ## Testing
59
+
60
+ ```
61
+ $ npm test
62
+ $ npm run coverage
63
+ ```
@@ -0,0 +1,34 @@
1
+ - Getting Started
2
+
3
+ - [Introduction](/)
4
+ - [Architecture](architecture.md)
5
+
6
+ - Query Building
7
+
8
+ - [Query Overview](query/README.md)
9
+ - [Create](query/create.md)
10
+ - [Read](query/read.md)
11
+ - [Update](query/update.md)
12
+ - [Delete](query/delete.md)
13
+ - [Count](query/count.md)
14
+
15
+ - Filtering & Sorting
16
+
17
+ - [Filters](filters.md)
18
+ - [Sorting](sorting.md)
19
+ - [Joins](joins.md)
20
+ - [Pagination](pagination.md)
21
+
22
+ - Dialects
23
+
24
+ - [Dialects Overview](dialects/README.md)
25
+ - [MySQL](dialects/mysql.md)
26
+ - [MSSQL](dialects/mssql.md)
27
+ - [SQLite](dialects/sqlite.md)
28
+ - [ALASQL](dialects/alasql.md)
29
+
30
+ - Advanced
31
+
32
+ - [Schema Integration](schema.md)
33
+ - [Query Overrides](query-overrides.md)
34
+ - [Configuration Reference](configuration.md)
@@ -0,0 +1,104 @@
1
+ # Architecture
2
+
3
+ FoxHound follows a clean separation between query configuration, dialect-specific generation, and result handling.
4
+
5
+ ## Overview
6
+
7
+ ```
8
+ ┌─────────────────────────────────────┐
9
+ │ Application Code │
10
+ │ query.setScope('Books') │
11
+ │ .addFilter('Genre','Sci-Fi') │
12
+ │ .setDialect('MySQL') │
13
+ │ .buildReadQuery() │
14
+ └──────────────┬──────────────────────┘
15
+
16
+ ┌──────────────▼──────────────────────┐
17
+ │ FoxHound Core │
18
+ │ - Parameters object (state) │
19
+ │ - Chainable configuration API │
20
+ │ - Dialect selection & delegation │
21
+ └──────────────┬──────────────────────┘
22
+
23
+ ┌──────────────▼──────────────────────┐
24
+ │ Dialect Engine │
25
+ │ MySQL │ MSSQL │ SQLite │ ALASQL │
26
+ │ - Generates SQL string │
27
+ │ - Populates named parameters │
28
+ │ - Applies schema-aware logic │
29
+ └──────────────┬──────────────────────┘
30
+
31
+ ┌──────────────▼──────────────────────┐
32
+ │ Query Output │
33
+ │ query.body → SQL string │
34
+ │ query.parameters → bound values │
35
+ │ query.schema → column metadata │
36
+ └─────────────────────────────────────┘
37
+ ```
38
+
39
+ ## Factory Pattern
40
+
41
+ FoxHound uses a factory constructor pattern. The module exports a bare constructor; you create instances by calling `.new()` with a Fable service context:
42
+
43
+ ```javascript
44
+ var libFoxHound = require('foxhound');
45
+ var tmpQuery = libFoxHound.new(_Fable);
46
+ ```
47
+
48
+ Every query instance gets its own UUID and independent parameter state, so multiple queries can be built concurrently without interference.
49
+
50
+ ## Parameters Object
51
+
52
+ All query state lives in a single `Parameters` object:
53
+
54
+ | Property | Type | Purpose |
55
+ |----------|------|---------|
56
+ | `scope` | String | Table or collection name |
57
+ | `dataElements` | Array | Column/field list |
58
+ | `begin` | Integer | Pagination start offset |
59
+ | `cap` | Integer | Maximum rows to return |
60
+ | `filter` | Array | Filter expression objects |
61
+ | `sort` | Array | Sort expression objects |
62
+ | `join` | Array | Join expression objects |
63
+ | `query` | Object | Generated query body, schema, records, and bound parameters |
64
+ | `queryOverride` | String | Custom query template |
65
+ | `indexHints` | Array | Index hints for the database engine |
66
+ | `userID` | Integer | The acting user (for audit stamps) |
67
+ | `result` | Object | Execution results (value, error, executed flag) |
68
+
69
+ ## Dialect Strategy
70
+
71
+ Each dialect is a module that exports a factory function accepting a Fable instance. The returned object exposes six methods that each accept a Parameters object and return a SQL string:
72
+
73
+ - `Create(pParameters)` — INSERT statement
74
+ - `Read(pParameters)` — SELECT statement
75
+ - `Update(pParameters)` — UPDATE statement
76
+ - `Delete(pParameters)` — UPDATE (soft) or DELETE (hard)
77
+ - `Undelete(pParameters)` — UPDATE to restore soft-deleted rows
78
+ - `Count(pParameters)` — SELECT COUNT statement
79
+
80
+ The dialect handles all syntax differences: quoting identifiers, parameter prefixes, pagination syntax, date functions, and identity column handling.
81
+
82
+ ## Chainable API
83
+
84
+ Every setter method returns `this`, enabling fluent composition:
85
+
86
+ ```javascript
87
+ tmpQuery
88
+ .setScope('Orders')
89
+ .setDataElements(['OrderID', 'Total', 'Status'])
90
+ .addFilter('Status', 'Pending')
91
+ .addSort({Column: 'Total', Direction: 'Descending'})
92
+ .setCap(50)
93
+ .setDialect('MySQL')
94
+ .buildReadQuery();
95
+ ```
96
+
97
+ ## Fable Integration
98
+
99
+ FoxHound depends on Fable for:
100
+
101
+ - **UUID Generation** — each query and record gets a unique identifier via `_Fable.getUUID()`
102
+ - **Logging** — filter, scope, and query errors are logged through `_Fable.log`
103
+ - **Utility Functions** — `_Fable.Utility.extend()` for parameter merging and `_Fable.Utility.template()` for query overrides
104
+ - **Configuration** — inherits any relevant settings from the Fable config
@@ -0,0 +1,217 @@
1
+ # Configuration Reference
2
+
3
+ This page documents all FoxHound configuration methods, properties, and their accepted values.
4
+
5
+ ## Query Configuration Methods
6
+
7
+ All setter methods return `this` for chaining.
8
+
9
+ ### setScope(pScope)
10
+
11
+ Set the primary table or collection for the query.
12
+
13
+ | Parameter | Type | Description |
14
+ |-----------|------|-------------|
15
+ | `pScope` | String | Table name |
16
+
17
+ ```javascript
18
+ tmpQuery.setScope('Books');
19
+ ```
20
+
21
+ ### setDialect(pDialectName)
22
+
23
+ Set the SQL dialect for query generation.
24
+
25
+ | Parameter | Type | Values |
26
+ |-----------|------|--------|
27
+ | `pDialectName` | String | `'MySQL'`, `'MSSQL'`, `'SQLite'`, `'ALASQL'`, `'English'`, `'MeadowEndpoints'` |
28
+
29
+ ```javascript
30
+ tmpQuery.setDialect('MySQL');
31
+ ```
32
+
33
+ ### setDataElements(pDataElements)
34
+
35
+ Set the columns to select. Pass `false` or omit to select all columns (`*`).
36
+
37
+ | Parameter | Type | Description |
38
+ |-----------|------|-------------|
39
+ | `pDataElements` | Array or String | Column name(s) |
40
+
41
+ ```javascript
42
+ tmpQuery.setDataElements(['Title', 'Author']);
43
+ tmpQuery.setDataElements('Title'); // Wraps in array automatically
44
+ ```
45
+
46
+ ### setDistinct(pDistinct)
47
+
48
+ Enable or disable DISTINCT results.
49
+
50
+ | Parameter | Type | Description |
51
+ |-----------|------|-------------|
52
+ | `pDistinct` | Boolean | `true` to enable DISTINCT |
53
+
54
+ ### setBegin(pBeginAmount)
55
+
56
+ Set the pagination starting offset.
57
+
58
+ | Parameter | Type | Description |
59
+ |-----------|------|-------------|
60
+ | `pBeginAmount` | Integer ≥ 0 | Zero-based row offset |
61
+
62
+ ### setCap(pCapAmount)
63
+
64
+ Set the maximum number of rows to return.
65
+
66
+ | Parameter | Type | Description |
67
+ |-----------|------|-------------|
68
+ | `pCapAmount` | Integer ≥ 0 | Maximum row count |
69
+
70
+ ### addFilter(pColumn, pValue, pOperator, pConnector, pParameter)
71
+
72
+ Add a filter expression.
73
+
74
+ | Parameter | Default | Description |
75
+ |-----------|---------|-------------|
76
+ | `pColumn` | *(required)* | Column name |
77
+ | `pValue` | *(required)* | Comparison value |
78
+ | `pOperator` | `'='` | Operator (`=`, `!=`, `>`, `>=`, `<`, `<=`, `LIKE`, `IN`, `NOT IN`, `IS NULL`, `IS NOT NULL`, `(`, `)`) |
79
+ | `pConnector` | `'AND'` | Logical connector (`AND`, `OR`, `NONE`) |
80
+ | `pParameter` | `pColumn` | Parameter name |
81
+
82
+ ### setFilter(pFilter)
83
+
84
+ Replace the entire filter array.
85
+
86
+ | Parameter | Type | Description |
87
+ |-----------|------|-------------|
88
+ | `pFilter` | Array or Object | Filter expression(s) |
89
+
90
+ ### addSort(pSort)
91
+
92
+ Add a sort expression.
93
+
94
+ | Parameter | Type | Description |
95
+ |-----------|------|-------------|
96
+ | `pSort` | String or Object | Column name or `{Column, Direction}` |
97
+
98
+ ### setSort(pSort)
99
+
100
+ Replace the entire sort array.
101
+
102
+ | Parameter | Type | Description |
103
+ |-----------|------|-------------|
104
+ | `pSort` | String, Object, or Array | Sort expression(s) |
105
+
106
+ ### addJoin(pTable, pFrom, pTo, pType)
107
+
108
+ Add a join expression.
109
+
110
+ | Parameter | Default | Description |
111
+ |-----------|---------|-------------|
112
+ | `pTable` | *(required)* | Table to join |
113
+ | `pFrom` | *(required)* | Column on join table |
114
+ | `pTo` | *(required)* | Column on base table |
115
+ | `pType` | `'INNER JOIN'` | Join type |
116
+
117
+ ### setJoin(pJoin)
118
+
119
+ Replace the entire join array.
120
+
121
+ | Parameter | Type | Description |
122
+ |-----------|------|-------------|
123
+ | `pJoin` | Object or Array | Join expression(s) |
124
+
125
+ ### addRecord(pRecord)
126
+
127
+ Add a record for CREATE or UPDATE operations.
128
+
129
+ | Parameter | Type | Description |
130
+ |-----------|------|-------------|
131
+ | `pRecord` | Object | Key-value pairs of column names and values |
132
+
133
+ ### setIDUser(pIDUser)
134
+
135
+ Set the user ID for audit stamp columns.
136
+
137
+ | Parameter | Type | Description |
138
+ |-----------|------|-------------|
139
+ | `pIDUser` | Integer ≥ 0 | User ID |
140
+
141
+ ### setDisableAutoIdentity(pFlag)
142
+
143
+ Disable automatic identity column handling.
144
+
145
+ ### setDisableAutoDateStamp(pFlag)
146
+
147
+ Disable automatic timestamp generation.
148
+
149
+ ### setDisableAutoUserStamp(pFlag)
150
+
151
+ Disable automatic user ID stamping.
152
+
153
+ ### setDisableDeleteTracking(pFlag)
154
+
155
+ Disable soft-delete behavior.
156
+
157
+ ### setLogLevel(pLogLevel)
158
+
159
+ Set the query logging verbosity.
160
+
161
+ | Level | Behavior |
162
+ |-------|----------|
163
+ | `0` | No logging (default) |
164
+ | `1` | Log generated queries |
165
+ | `2` | Log queries and non-parameterized versions |
166
+ | `3` | Log everything |
167
+
168
+ ## Properties
169
+
170
+ | Property | Type | Access | Description |
171
+ |----------|------|--------|-------------|
172
+ | `query` | Object | get/set | The generated query (`body`, `schema`, `records`, `parameters`) |
173
+ | `result` | Object | get/set | Execution results (`executed`, `value`, `error`) |
174
+ | `parameters` | Object | get/set | Full parameters state |
175
+ | `dialect` | Object | get | Current dialect object |
176
+ | `uuid` | String | get | Unique identifier for this query |
177
+ | `logLevel` | Integer | get | Current log level |
178
+ | `indexHints` | Array | get/set | Index hints for the database engine |
179
+
180
+ ## Utility Methods
181
+
182
+ ### clone()
183
+
184
+ Create a new FoxHound query with the same scope, begin, cap, schema, dataElements, sorts, and filters.
185
+
186
+ ```javascript
187
+ var tmpClone = tmpQuery.clone();
188
+ ```
189
+
190
+ ### resetParameters()
191
+
192
+ Reset the query to its default state.
193
+
194
+ ```javascript
195
+ tmpQuery.resetParameters();
196
+ ```
197
+
198
+ ### mergeParameters(pFromParameters)
199
+
200
+ Merge an object of parameters into the current state.
201
+
202
+ ```javascript
203
+ tmpQuery.mergeParameters({cap: 50, begin: 0});
204
+ ```
205
+
206
+ ## Build Methods
207
+
208
+ | Method | Generates |
209
+ |--------|-----------|
210
+ | `buildCreateQuery()` | INSERT statement |
211
+ | `buildReadQuery()` | SELECT statement |
212
+ | `buildUpdateQuery()` | UPDATE statement |
213
+ | `buildDeleteQuery()` | DELETE or soft-delete UPDATE |
214
+ | `buildUndeleteQuery()` | Restore soft-deleted rows |
215
+ | `buildCountQuery()` | SELECT COUNT statement |
216
+
217
+ All build methods return `this` for chaining. The generated SQL is available at `query.body` and bound parameters at `query.parameters`.
package/docs/cover.md ADDED
@@ -0,0 +1,11 @@
1
+ # FoxHound <small>2</small>
2
+
3
+ > A fluent query generation DSL for Node.js and the browser
4
+
5
+ - Chainable API that generates dialect-specific SQL
6
+ - Parameterized queries for safe, injection-free operation
7
+ - Schema-aware with automatic identity, timestamp, and soft-delete management
8
+ - Multiple dialects: MySQL, MSSQL, SQLite, ALASQL, and more
9
+
10
+ [GitHub](https://github.com/stevenvelozo/foxhound)
11
+ [Get Started](#foxhound)