foxhound 2.0.25 → 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 +22 -22
- package/docs/README.md +24 -24
- package/docs/_cover.md +1 -1
- package/docs/_version.json +7 -0
- package/docs/api/behaviorFlags.md +1 -1
- package/docs/api/buildQuery.md +2 -2
- package/docs/api/clone.md +1 -1
- package/docs/api/setScope.md +1 -1
- package/docs/architecture.md +4 -4
- package/docs/css/docuserve.css +277 -23
- package/docs/dialects/README.md +4 -4
- package/docs/dialects/postgresql.md +1 -1
- package/docs/dialects/sqlite.md +5 -5
- package/docs/index.html +2 -2
- package/docs/joins.md +3 -3
- package/docs/query/README.md +4 -4
- package/docs/query/create.md +4 -4
- package/docs/query/update.md +10 -10
- package/docs/query-overrides.md +1 -1
- package/docs/quickstart.md +5 -5
- package/docs/retold-catalog.json +1 -1
- package/docs/retold-keyword-index.json +1 -1
- package/docs/schema.md +32 -32
- package/docs/sorting.md +4 -4
- package/package.json +3 -2
- package/source/dialects/ALASQL/FoxHound-Dialect-ALASQL.js +10 -8
- package/source/dialects/DGraph/FoxHound-Dialect-DGraph.js +8 -6
- package/source/dialects/MicrosoftSQL/FoxHound-Dialect-MSSQL.js +120 -0
- package/source/dialects/MongoDB/FoxHound-Dialect-MongoDB.js +8 -6
- package/source/dialects/MySQL/FoxHound-Dialect-MySQL.js +11 -8
- package/source/dialects/PostgreSQL/FoxHound-Dialect-PostgreSQL.js +10 -6
- package/source/dialects/SQLite/FoxHound-Dialect-SQLite.js +11 -8
- package/source/dialects/Solr/FoxHound-Dialect-Solr.js +8 -6
- package/test/FoxHound-Dialect-ALASQL_tests.js +3 -1
- package/test/FoxHound-Dialect-MySQL_tests.js +3 -1
- package/test/FoxHound-Dialect-SQLite_tests.js +3 -1
- package/test/Foxhound-Dialect-MSSQL_tests.js +59 -4
package/README.md
CHANGED
|
@@ -6,15 +6,15 @@ FoxHound is a database query builder that generates dialect-specific SQL from a
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **Chainable API**
|
|
10
|
-
- **Multiple Dialects**
|
|
11
|
-
- **Parameterized Queries**
|
|
12
|
-
- **Schema-Aware**
|
|
13
|
-
- **Full CRUD + Count**
|
|
14
|
-
- **Query Overrides**
|
|
15
|
-
- **Filtering & Sorting**
|
|
16
|
-
- **Joins & Pagination**
|
|
17
|
-
- **Fable Integration**
|
|
9
|
+
- **Chainable API** -- every configuration method returns the query object for fluent composition
|
|
10
|
+
- **Multiple Dialects** -- generate SQL for MySQL, PostgreSQL, 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
18
|
|
|
19
19
|
## Quick Start
|
|
20
20
|
|
|
@@ -55,14 +55,14 @@ FoxHound follows a configure-then-build pattern. You create a query instance, c
|
|
|
55
55
|
```
|
|
56
56
|
Application Code
|
|
57
57
|
└── FoxHound Query
|
|
58
|
-
├── setScope('Books')
|
|
59
|
-
├── addFilter('Genre', '...')
|
|
60
|
-
├── addSort('Title')
|
|
61
|
-
├── setCap(25)
|
|
62
|
-
├── setDialect('MySQL')
|
|
63
|
-
└── buildReadQuery()
|
|
64
|
-
├── query.body
|
|
65
|
-
└── query.parameters
|
|
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
66
|
```
|
|
67
67
|
|
|
68
68
|
## Dialects
|
|
@@ -83,14 +83,14 @@ When a schema is attached, FoxHound automatically manages special columns:
|
|
|
83
83
|
|
|
84
84
|
| Type | Description |
|
|
85
85
|
|------|-------------|
|
|
86
|
-
| `AutoIdentity` | Auto-increment primary key
|
|
86
|
+
| `AutoIdentity` | Auto-increment primary key -- `NULL` on insert, skipped on update |
|
|
87
87
|
| `AutoGUID` | Automatically generated UUID on insert |
|
|
88
88
|
| `CreateDate` / `CreateIDUser` | Auto-populated on insert only |
|
|
89
89
|
| `UpdateDate` / `UpdateIDUser` | Auto-populated on insert and update |
|
|
90
90
|
| `DeleteDate` / `DeleteIDUser` | Auto-populated on soft delete |
|
|
91
|
-
| `Deleted` | Soft-delete flag
|
|
92
|
-
| `JSON` | Structured JSON data
|
|
93
|
-
| `JSONProxy` | JSON stored in a different SQL column
|
|
91
|
+
| `Deleted` | Soft-delete flag -- auto-filtered in reads |
|
|
92
|
+
| `JSON` | Structured JSON data -- serialized to `TEXT` on write, parsed on read |
|
|
93
|
+
| `JSONProxy` | JSON stored in a different SQL column -- uses `StorageColumn` for SQL, virtual name for objects |
|
|
94
94
|
|
|
95
95
|
## Filter Operators
|
|
96
96
|
|
|
@@ -125,7 +125,7 @@ npm run docker-dev-build
|
|
|
125
125
|
npm run docker-dev-run
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
-
3. Open http://localhost:24238/
|
|
128
|
+
3. Open http://localhost:24238/ -- the password is "retold"
|
|
129
129
|
|
|
130
130
|
## Documentation
|
|
131
131
|
|
package/docs/README.md
CHANGED
|
@@ -6,15 +6,15 @@ FoxHound is a fluent query generation DSL for Node.js and the browser. It produ
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **Chainable API**
|
|
10
|
-
- **Multiple Dialects**
|
|
11
|
-
- **Parameterized Queries**
|
|
12
|
-
- **Schema-Aware**
|
|
13
|
-
- **Full CRUD + Count**
|
|
14
|
-
- **Query Overrides**
|
|
15
|
-
- **Filtering & Sorting**
|
|
16
|
-
- **Joins & Pagination**
|
|
17
|
-
- **Fable Integration**
|
|
9
|
+
- **Chainable API** -- every configuration method returns the query object, so you can compose queries in a single expression
|
|
10
|
+
- **Multiple Dialects** -- generate SQL for MySQL, PostgreSQL, Microsoft SQL Server, SQLite, ALASQL, or plain English, all from the same code
|
|
11
|
+
- **Parameterized Queries** -- user-supplied values are always bound as named parameters, preventing SQL injection
|
|
12
|
+
- **Schema-Aware** -- when a schema is provided, FoxHound automatically manages 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** -- supply an underscore-style template to customize query generation while still benefiting from 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
18
|
|
|
19
19
|
## Quick Start
|
|
20
20
|
|
|
@@ -48,24 +48,24 @@ console.log(tmpQuery.query.parameters);
|
|
|
48
48
|
|
|
49
49
|
## How It Works
|
|
50
50
|
|
|
51
|
-
1. **Create a Query**
|
|
52
|
-
2. **Configure**
|
|
53
|
-
3. **Set a Dialect**
|
|
54
|
-
4. **Build**
|
|
55
|
-
5. **Execute**
|
|
51
|
+
1. **Create a Query** -- instantiate via `foxhound.new(fable)` or through a Fable service
|
|
52
|
+
2. **Configure** -- chain methods to set scope (table), fields, filters, sorts, joins, and pagination
|
|
53
|
+
3. **Set a Dialect** -- call `.setDialect('MySQL')` (or PostgreSQL, MSSQL, SQLite, ALASQL, English)
|
|
54
|
+
4. **Build** -- call a build method such as `.buildReadQuery()` to generate the SQL
|
|
55
|
+
5. **Execute** -- read the generated SQL from `.query.body` and bound parameters from `.query.parameters`
|
|
56
56
|
|
|
57
57
|
## Documentation
|
|
58
58
|
|
|
59
|
-
- [Quickstart](quickstart.md)
|
|
60
|
-
- [Architecture](architecture.md)
|
|
61
|
-
- [Filters](filters.md)
|
|
62
|
-
- [Sorting](sorting.md)
|
|
63
|
-
- [Joins](joins.md)
|
|
64
|
-
- [Pagination](pagination.md)
|
|
65
|
-
- [Schema Integration](schema.md)
|
|
66
|
-
- [Dialects](dialects/README.md)
|
|
67
|
-
- [API Reference](api/README.md)
|
|
68
|
-
- [Query Overrides](query-overrides.md)
|
|
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
69
|
|
|
70
70
|
## Related Packages
|
|
71
71
|
|
package/docs/_cover.md
CHANGED
|
@@ -120,4 +120,4 @@ tmpQuery
|
|
|
120
120
|
.setDisableDeleteTracking(true);
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
This gives you full manual control over all column values
|
|
123
|
+
This gives you full manual control over all column values -- useful for data migration or import scenarios.
|
package/docs/api/buildQuery.md
CHANGED
|
@@ -89,7 +89,7 @@ Generate a soft-delete UPDATE or a hard DELETE.
|
|
|
89
89
|
When a schema has a `Deleted` column type and delete tracking is enabled:
|
|
90
90
|
|
|
91
91
|
```javascript
|
|
92
|
-
// Soft delete
|
|
92
|
+
// Soft delete -- generates an UPDATE
|
|
93
93
|
tmpQuery.buildDeleteQuery();
|
|
94
94
|
// => UPDATE `Books` SET Deleted = 1, DeleteDate = NOW(3), ...
|
|
95
95
|
```
|
|
@@ -97,7 +97,7 @@ tmpQuery.buildDeleteQuery();
|
|
|
97
97
|
When no schema or delete tracking is disabled:
|
|
98
98
|
|
|
99
99
|
```javascript
|
|
100
|
-
// Hard delete
|
|
100
|
+
// Hard delete -- generates a DELETE
|
|
101
101
|
tmpQuery.setDisableDeleteTracking(true).buildDeleteQuery();
|
|
102
102
|
// => DELETE FROM `Books` WHERE IDBook = :IDBook_w0;
|
|
103
103
|
```
|
package/docs/api/clone.md
CHANGED
|
@@ -18,7 +18,7 @@ Returns a new FoxHound query instance with copies of the current scope, begin, c
|
|
|
18
18
|
|
|
19
19
|
### Description
|
|
20
20
|
|
|
21
|
-
Cloning is useful when you need to build multiple similar queries from the same base configuration. The cloned query has its own independent state
|
|
21
|
+
Cloning is useful when you need to build multiple similar queries from the same base configuration. The cloned query has its own independent state -- changes to the clone do not affect the original.
|
|
22
22
|
|
|
23
23
|
### Example
|
|
24
24
|
|
package/docs/api/setScope.md
CHANGED
|
@@ -20,7 +20,7 @@ Returns `this` for chaining.
|
|
|
20
20
|
|
|
21
21
|
## Description
|
|
22
22
|
|
|
23
|
-
The scope defines which table (or collection, in NoSQL dialects) the query targets. This is required for all query types
|
|
23
|
+
The scope defines which table (or collection, in NoSQL dialects) the query targets. This is required for all query types -- it appears as the `FROM` clause in SELECT, `INSERT INTO` in CREATE, `UPDATE` in UPDATE, and `DELETE FROM` in DELETE.
|
|
24
24
|
|
|
25
25
|
FoxHound validates that the input is a string. Non-string values are ignored and an error is logged.
|
|
26
26
|
|
package/docs/architecture.md
CHANGED
|
@@ -168,10 +168,10 @@ tmpQuery
|
|
|
168
168
|
|
|
169
169
|
FoxHound depends on Fable for:
|
|
170
170
|
|
|
171
|
-
- **UUID Generation**
|
|
172
|
-
- **Logging**
|
|
173
|
-
- **Utility Functions**
|
|
174
|
-
- **Configuration**
|
|
171
|
+
- **UUID Generation** -- each query and record gets a unique identifier via `_Fable.getUUID()`
|
|
172
|
+
- **Logging** -- filter, scope, and query errors are logged through `_Fable.log`
|
|
173
|
+
- **Utility Functions** -- `_Fable.Utility.extend()` for parameter merging and `_Fable.Utility.template()` for query overrides
|
|
174
|
+
- **Configuration** -- inherits any relevant settings from the Fable config
|
|
175
175
|
|
|
176
176
|
## Schema-Aware Generation
|
|
177
177
|
|
package/docs/css/docuserve.css
CHANGED
|
@@ -1,73 +1,327 @@
|
|
|
1
1
|
/* ============================================================================
|
|
2
|
-
Pict Docuserve - Base Styles
|
|
2
|
+
Pict Docuserve - Base Styles & Theme Variables
|
|
3
3
|
============================================================================ */
|
|
4
4
|
|
|
5
|
-
/*
|
|
6
|
-
|
|
5
|
+
/* ----------------------------------------------------------------------------
|
|
6
|
+
Theme variables — light defaults on :root.
|
|
7
|
+
Dark mode applies when either:
|
|
8
|
+
(a) the user explicitly selected dark via <html data-theme="dark">
|
|
9
|
+
(b) the user hasn't chosen anything AND the system prefers dark
|
|
10
|
+
An explicit <html data-theme="light"> pins the light palette regardless.
|
|
11
|
+
---------------------------------------------------------------------------- */
|
|
12
|
+
|
|
13
|
+
:root
|
|
14
|
+
{
|
|
15
|
+
/* Surfaces */
|
|
16
|
+
--docuserve-bg: #FDFBF7;
|
|
17
|
+
--docuserve-bg-elevated: #FFFFFF;
|
|
18
|
+
--docuserve-border: #DDD6CA;
|
|
19
|
+
--docuserve-border-soft: #EAE3D8;
|
|
20
|
+
|
|
21
|
+
/* Text */
|
|
22
|
+
--docuserve-text: #2A241E;
|
|
23
|
+
--docuserve-text-strong: #3D3229;
|
|
24
|
+
--docuserve-text-muted: #5E5549;
|
|
25
|
+
--docuserve-text-dim: #8A7F72;
|
|
26
|
+
|
|
27
|
+
/* Accent / links */
|
|
28
|
+
--docuserve-accent: #2E7D74;
|
|
29
|
+
--docuserve-accent-hover: #236660;
|
|
30
|
+
|
|
31
|
+
/* Top bar */
|
|
32
|
+
--docuserve-topbar-bg: #3D3229;
|
|
33
|
+
--docuserve-topbar-text: #E8E0D4;
|
|
34
|
+
--docuserve-topbar-text-muted: #B5AA9A;
|
|
35
|
+
--docuserve-topbar-text-dim: #8A7F72;
|
|
36
|
+
--docuserve-topbar-hover-bg: #524438;
|
|
37
|
+
--docuserve-topbar-version-bg: rgba(255, 255, 255, 0.06);
|
|
38
|
+
--docuserve-topbar-version-border: rgba(255, 255, 255, 0.08);
|
|
39
|
+
--docuserve-topbar-version-text: #B5AA9A;
|
|
40
|
+
|
|
41
|
+
/* Sidebar */
|
|
42
|
+
--docuserve-sidebar-bg: #FAF7F1;
|
|
43
|
+
--docuserve-sidebar-border: #DDD6CA;
|
|
44
|
+
--docuserve-sidebar-border-soft: #E5DED1;
|
|
45
|
+
--docuserve-sidebar-text: #423D37;
|
|
46
|
+
--docuserve-sidebar-group-title: #3D3229;
|
|
47
|
+
--docuserve-sidebar-module-text: #5E5549;
|
|
48
|
+
--docuserve-sidebar-hover-bg: #EAE3D8;
|
|
49
|
+
--docuserve-sidebar-hover-text: #2E7D74;
|
|
50
|
+
--docuserve-sidebar-active-bg: #E5DED1;
|
|
51
|
+
--docuserve-sidebar-active-text: #2E7D74;
|
|
52
|
+
--docuserve-sidebar-search-bg: #FFFFFF;
|
|
53
|
+
--docuserve-sidebar-search-border: #DDD6CA;
|
|
54
|
+
|
|
55
|
+
/* Inline code */
|
|
56
|
+
--docuserve-inline-code-bg: #F0ECE4;
|
|
57
|
+
--docuserve-inline-code-text: #9E3A50;
|
|
58
|
+
|
|
59
|
+
/* Code block panel */
|
|
60
|
+
--docuserve-code-bg: #F6F3EE;
|
|
61
|
+
--docuserve-code-border: #E5DED1;
|
|
62
|
+
--docuserve-code-gutter-bg: #EFEAE0;
|
|
63
|
+
--docuserve-code-gutter-border: #DDD6CA;
|
|
64
|
+
--docuserve-code-gutter-text: #A59986;
|
|
65
|
+
--docuserve-code-text: #2A241E;
|
|
66
|
+
|
|
67
|
+
/* Syntax tokens — low-chroma dark-on-light palette */
|
|
68
|
+
--docuserve-tok-keyword: #A03472;
|
|
69
|
+
--docuserve-tok-string: #1A6640;
|
|
70
|
+
--docuserve-tok-number: #B25A00;
|
|
71
|
+
--docuserve-tok-comment: #8A7F72;
|
|
72
|
+
--docuserve-tok-operator: #2E7D74;
|
|
73
|
+
--docuserve-tok-punctuation: #2A241E;
|
|
74
|
+
--docuserve-tok-function: #2A5DB0;
|
|
75
|
+
--docuserve-tok-property: #9E3A50;
|
|
76
|
+
--docuserve-tok-tag: #9E3A50;
|
|
77
|
+
--docuserve-tok-attr-name: #B25A00;
|
|
78
|
+
--docuserve-tok-attr-value: #1A6640;
|
|
79
|
+
|
|
80
|
+
/* Tables, blockquotes, mermaid */
|
|
81
|
+
--docuserve-table-header-bg: #F5F0E8;
|
|
82
|
+
--docuserve-table-row-alt-bg: #F9F6F0;
|
|
83
|
+
--docuserve-blockquote-bg: #F7F5F0;
|
|
84
|
+
--docuserve-blockquote-border: #2E7D74;
|
|
85
|
+
--docuserve-blockquote-text: #5E5549;
|
|
86
|
+
--docuserve-mermaid-bg: #FFFFFF;
|
|
87
|
+
|
|
88
|
+
/* Scrollbars */
|
|
89
|
+
--docuserve-scrollbar-track: #F5F0E8;
|
|
90
|
+
--docuserve-scrollbar-thumb: #D4CCBE;
|
|
91
|
+
--docuserve-scrollbar-thumb-hover: #B5AA9A;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@media (prefers-color-scheme: dark)
|
|
95
|
+
{
|
|
96
|
+
:root:not([data-theme="light"])
|
|
97
|
+
{
|
|
98
|
+
--docuserve-bg: #15120F;
|
|
99
|
+
--docuserve-bg-elevated: #1B1814;
|
|
100
|
+
--docuserve-border: #2F2823;
|
|
101
|
+
--docuserve-border-soft: #26211C;
|
|
102
|
+
|
|
103
|
+
--docuserve-text: #E8E0D4;
|
|
104
|
+
--docuserve-text-strong: #F2ECE0;
|
|
105
|
+
--docuserve-text-muted: #B5AA9A;
|
|
106
|
+
--docuserve-text-dim: #7A6F62;
|
|
107
|
+
|
|
108
|
+
--docuserve-accent: #5DB8A8;
|
|
109
|
+
--docuserve-accent-hover: #7FCCB8;
|
|
110
|
+
|
|
111
|
+
--docuserve-topbar-bg: #1A1612;
|
|
112
|
+
--docuserve-topbar-text: #E8E0D4;
|
|
113
|
+
--docuserve-topbar-text-muted: #B5AA9A;
|
|
114
|
+
--docuserve-topbar-text-dim: #7A6F62;
|
|
115
|
+
--docuserve-topbar-hover-bg: #2A241E;
|
|
116
|
+
--docuserve-topbar-version-bg: rgba(255, 255, 255, 0.05);
|
|
117
|
+
--docuserve-topbar-version-border: rgba(255, 255, 255, 0.09);
|
|
118
|
+
--docuserve-topbar-version-text: #B5AA9A;
|
|
119
|
+
|
|
120
|
+
--docuserve-sidebar-bg: #1B1814;
|
|
121
|
+
--docuserve-sidebar-border: #2F2823;
|
|
122
|
+
--docuserve-sidebar-border-soft: #26211C;
|
|
123
|
+
--docuserve-sidebar-text: #C9C0B3;
|
|
124
|
+
--docuserve-sidebar-group-title: #F2ECE0;
|
|
125
|
+
--docuserve-sidebar-module-text: #B5AA9A;
|
|
126
|
+
--docuserve-sidebar-hover-bg: #2A241E;
|
|
127
|
+
--docuserve-sidebar-hover-text: #7FCCB8;
|
|
128
|
+
--docuserve-sidebar-active-bg: #2F2823;
|
|
129
|
+
--docuserve-sidebar-active-text: #7FCCB8;
|
|
130
|
+
--docuserve-sidebar-search-bg: #26211C;
|
|
131
|
+
--docuserve-sidebar-search-border: #2F2823;
|
|
132
|
+
|
|
133
|
+
--docuserve-inline-code-bg: #2A241E;
|
|
134
|
+
--docuserve-inline-code-text: #E8B07A;
|
|
135
|
+
|
|
136
|
+
--docuserve-code-bg: #1E1A17;
|
|
137
|
+
--docuserve-code-border: #2F2823;
|
|
138
|
+
--docuserve-code-gutter-bg: #17130F;
|
|
139
|
+
--docuserve-code-gutter-border: #2F2823;
|
|
140
|
+
--docuserve-code-gutter-text: #6A6052;
|
|
141
|
+
--docuserve-code-text: #E8E0D4;
|
|
142
|
+
|
|
143
|
+
--docuserve-tok-keyword: #C678DD;
|
|
144
|
+
--docuserve-tok-string: #98C379;
|
|
145
|
+
--docuserve-tok-number: #D19A66;
|
|
146
|
+
--docuserve-tok-comment: #7F848E;
|
|
147
|
+
--docuserve-tok-operator: #56B6C2;
|
|
148
|
+
--docuserve-tok-punctuation: #E8E0D4;
|
|
149
|
+
--docuserve-tok-function: #61AFEF;
|
|
150
|
+
--docuserve-tok-property: #E06C75;
|
|
151
|
+
--docuserve-tok-tag: #E06C75;
|
|
152
|
+
--docuserve-tok-attr-name: #D19A66;
|
|
153
|
+
--docuserve-tok-attr-value: #98C379;
|
|
154
|
+
|
|
155
|
+
--docuserve-table-header-bg: #26211C;
|
|
156
|
+
--docuserve-table-row-alt-bg: #1F1B17;
|
|
157
|
+
--docuserve-blockquote-bg: #1F1B17;
|
|
158
|
+
--docuserve-blockquote-border: #5DB8A8;
|
|
159
|
+
--docuserve-blockquote-text: #C9C0B3;
|
|
160
|
+
--docuserve-mermaid-bg: #E8E0D4;
|
|
161
|
+
|
|
162
|
+
--docuserve-scrollbar-track: #1B1814;
|
|
163
|
+
--docuserve-scrollbar-thumb: #3A322B;
|
|
164
|
+
--docuserve-scrollbar-thumb-hover: #524438;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
:root[data-theme="dark"]
|
|
169
|
+
{
|
|
170
|
+
--docuserve-bg: #15120F;
|
|
171
|
+
--docuserve-bg-elevated: #1B1814;
|
|
172
|
+
--docuserve-border: #2F2823;
|
|
173
|
+
--docuserve-border-soft: #26211C;
|
|
174
|
+
|
|
175
|
+
--docuserve-text: #E8E0D4;
|
|
176
|
+
--docuserve-text-strong: #F2ECE0;
|
|
177
|
+
--docuserve-text-muted: #B5AA9A;
|
|
178
|
+
--docuserve-text-dim: #7A6F62;
|
|
179
|
+
|
|
180
|
+
--docuserve-accent: #5DB8A8;
|
|
181
|
+
--docuserve-accent-hover: #7FCCB8;
|
|
182
|
+
|
|
183
|
+
--docuserve-topbar-bg: #1A1612;
|
|
184
|
+
--docuserve-topbar-text: #E8E0D4;
|
|
185
|
+
--docuserve-topbar-text-muted: #B5AA9A;
|
|
186
|
+
--docuserve-topbar-text-dim: #7A6F62;
|
|
187
|
+
--docuserve-topbar-hover-bg: #2A241E;
|
|
188
|
+
--docuserve-topbar-version-bg: rgba(255, 255, 255, 0.05);
|
|
189
|
+
--docuserve-topbar-version-border: rgba(255, 255, 255, 0.09);
|
|
190
|
+
--docuserve-topbar-version-text: #B5AA9A;
|
|
191
|
+
|
|
192
|
+
--docuserve-sidebar-bg: #1B1814;
|
|
193
|
+
--docuserve-sidebar-border: #2F2823;
|
|
194
|
+
--docuserve-sidebar-border-soft: #26211C;
|
|
195
|
+
--docuserve-sidebar-text: #C9C0B3;
|
|
196
|
+
--docuserve-sidebar-group-title: #F2ECE0;
|
|
197
|
+
--docuserve-sidebar-module-text: #B5AA9A;
|
|
198
|
+
--docuserve-sidebar-hover-bg: #2A241E;
|
|
199
|
+
--docuserve-sidebar-hover-text: #7FCCB8;
|
|
200
|
+
--docuserve-sidebar-active-bg: #2F2823;
|
|
201
|
+
--docuserve-sidebar-active-text: #7FCCB8;
|
|
202
|
+
--docuserve-sidebar-search-bg: #26211C;
|
|
203
|
+
--docuserve-sidebar-search-border: #2F2823;
|
|
204
|
+
|
|
205
|
+
--docuserve-inline-code-bg: #2A241E;
|
|
206
|
+
--docuserve-inline-code-text: #E8B07A;
|
|
207
|
+
|
|
208
|
+
--docuserve-code-bg: #1E1A17;
|
|
209
|
+
--docuserve-code-border: #2F2823;
|
|
210
|
+
--docuserve-code-gutter-bg: #17130F;
|
|
211
|
+
--docuserve-code-gutter-border: #2F2823;
|
|
212
|
+
--docuserve-code-gutter-text: #6A6052;
|
|
213
|
+
--docuserve-code-text: #E8E0D4;
|
|
214
|
+
|
|
215
|
+
--docuserve-tok-keyword: #C678DD;
|
|
216
|
+
--docuserve-tok-string: #98C379;
|
|
217
|
+
--docuserve-tok-number: #D19A66;
|
|
218
|
+
--docuserve-tok-comment: #7F848E;
|
|
219
|
+
--docuserve-tok-operator: #56B6C2;
|
|
220
|
+
--docuserve-tok-punctuation: #E8E0D4;
|
|
221
|
+
--docuserve-tok-function: #61AFEF;
|
|
222
|
+
--docuserve-tok-property: #E06C75;
|
|
223
|
+
--docuserve-tok-tag: #E06C75;
|
|
224
|
+
--docuserve-tok-attr-name: #D19A66;
|
|
225
|
+
--docuserve-tok-attr-value: #98C379;
|
|
226
|
+
|
|
227
|
+
--docuserve-table-header-bg: #26211C;
|
|
228
|
+
--docuserve-table-row-alt-bg: #1F1B17;
|
|
229
|
+
--docuserve-blockquote-bg: #1F1B17;
|
|
230
|
+
--docuserve-blockquote-border: #5DB8A8;
|
|
231
|
+
--docuserve-blockquote-text: #C9C0B3;
|
|
232
|
+
--docuserve-mermaid-bg: #E8E0D4;
|
|
233
|
+
|
|
234
|
+
--docuserve-scrollbar-track: #1B1814;
|
|
235
|
+
--docuserve-scrollbar-thumb: #3A322B;
|
|
236
|
+
--docuserve-scrollbar-thumb-hover: #524438;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* ----------------------------------------------------------------------------
|
|
240
|
+
Reset and base
|
|
241
|
+
---------------------------------------------------------------------------- */
|
|
242
|
+
|
|
243
|
+
*, *::before, *::after
|
|
244
|
+
{
|
|
7
245
|
box-sizing: border-box;
|
|
8
246
|
}
|
|
9
247
|
|
|
10
|
-
html, body
|
|
248
|
+
html, body
|
|
249
|
+
{
|
|
11
250
|
margin: 0;
|
|
12
251
|
padding: 0;
|
|
13
252
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
14
253
|
font-size: 16px;
|
|
15
254
|
line-height: 1.5;
|
|
16
|
-
color:
|
|
17
|
-
background-color:
|
|
255
|
+
color: var(--docuserve-text);
|
|
256
|
+
background-color: var(--docuserve-bg);
|
|
18
257
|
-webkit-font-smoothing: antialiased;
|
|
19
258
|
-moz-osx-font-smoothing: grayscale;
|
|
259
|
+
transition: background-color 0.15s ease, color 0.15s ease;
|
|
20
260
|
}
|
|
21
261
|
|
|
22
262
|
/* Typography */
|
|
23
|
-
h1, h2, h3, h4, h5, h6
|
|
263
|
+
h1, h2, h3, h4, h5, h6
|
|
264
|
+
{
|
|
24
265
|
margin-top: 0;
|
|
25
266
|
line-height: 1.3;
|
|
267
|
+
color: var(--docuserve-text-strong);
|
|
26
268
|
}
|
|
27
269
|
|
|
28
|
-
a
|
|
29
|
-
|
|
270
|
+
a
|
|
271
|
+
{
|
|
272
|
+
color: var(--docuserve-accent);
|
|
30
273
|
text-decoration: none;
|
|
31
274
|
}
|
|
32
275
|
|
|
33
|
-
a:hover
|
|
34
|
-
|
|
276
|
+
a:hover
|
|
277
|
+
{
|
|
278
|
+
color: var(--docuserve-accent-hover);
|
|
35
279
|
}
|
|
36
280
|
|
|
37
281
|
/* Application container */
|
|
38
|
-
#Docuserve-Application-Container
|
|
282
|
+
#Docuserve-Application-Container
|
|
283
|
+
{
|
|
39
284
|
min-height: 100vh;
|
|
40
285
|
}
|
|
41
286
|
|
|
42
287
|
/* Utility: scrollbar styling */
|
|
43
|
-
::-webkit-scrollbar
|
|
288
|
+
::-webkit-scrollbar
|
|
289
|
+
{
|
|
44
290
|
width: 8px;
|
|
291
|
+
height: 8px;
|
|
45
292
|
}
|
|
46
293
|
|
|
47
|
-
::-webkit-scrollbar-track
|
|
48
|
-
|
|
294
|
+
::-webkit-scrollbar-track
|
|
295
|
+
{
|
|
296
|
+
background: var(--docuserve-scrollbar-track);
|
|
49
297
|
}
|
|
50
298
|
|
|
51
|
-
::-webkit-scrollbar-thumb
|
|
52
|
-
|
|
299
|
+
::-webkit-scrollbar-thumb
|
|
300
|
+
{
|
|
301
|
+
background: var(--docuserve-scrollbar-thumb);
|
|
53
302
|
border-radius: 4px;
|
|
54
303
|
}
|
|
55
304
|
|
|
56
|
-
::-webkit-scrollbar-thumb:hover
|
|
57
|
-
|
|
305
|
+
::-webkit-scrollbar-thumb:hover
|
|
306
|
+
{
|
|
307
|
+
background: var(--docuserve-scrollbar-thumb-hover);
|
|
58
308
|
}
|
|
59
309
|
|
|
60
310
|
/* Responsive adjustments */
|
|
61
|
-
@media (max-width: 768px)
|
|
62
|
-
|
|
311
|
+
@media (max-width: 768px)
|
|
312
|
+
{
|
|
313
|
+
html
|
|
314
|
+
{
|
|
63
315
|
font-size: 14px;
|
|
64
316
|
}
|
|
65
317
|
|
|
66
|
-
#Docuserve-Sidebar-Container
|
|
318
|
+
#Docuserve-Sidebar-Container
|
|
319
|
+
{
|
|
67
320
|
display: none;
|
|
68
321
|
}
|
|
69
322
|
|
|
70
|
-
.docuserve-body
|
|
323
|
+
.docuserve-body
|
|
324
|
+
{
|
|
71
325
|
flex-direction: column;
|
|
72
326
|
}
|
|
73
327
|
}
|
package/docs/dialects/README.md
CHANGED
|
@@ -45,10 +45,10 @@ Each method receives the full Parameters object and returns a SQL string (or `fa
|
|
|
45
45
|
|
|
46
46
|
All SQL dialects share these behaviors:
|
|
47
47
|
|
|
48
|
-
- **Parameterized values**
|
|
49
|
-
- **Schema-aware column management**
|
|
50
|
-
- **Soft-delete filtering**
|
|
51
|
-
- **Query overrides**
|
|
48
|
+
- **Parameterized values** -- user data is always bound as named parameters, never interpolated
|
|
49
|
+
- **Schema-aware column management** -- AutoIdentity, timestamps, user stamps, and soft-delete columns are handled automatically based on schema type annotations
|
|
50
|
+
- **Soft-delete filtering** -- Read and Count queries automatically exclude rows where the `Deleted` column is `1` (when schema is present)
|
|
51
|
+
- **Query overrides** -- Read and Count queries support underscore templates for custom SQL generation
|
|
52
52
|
|
|
53
53
|
## Choosing a Dialect
|
|
54
54
|
|
|
@@ -56,7 +56,7 @@ INSERT INTO "Books" ( "IDBook", "Title") VALUES ( DEFAULT, :Title_1) RETURNING *
|
|
|
56
56
|
|
|
57
57
|
## RETURNING Clause
|
|
58
58
|
|
|
59
|
-
All INSERT statements include `RETURNING *`, which returns the full inserted row
|
|
59
|
+
All INSERT statements include `RETURNING *`, which returns the full inserted row -- including any auto-generated values like serial IDs and default timestamps.
|
|
60
60
|
|
|
61
61
|
## Joins
|
|
62
62
|
|
package/docs/dialects/sqlite.md
CHANGED
|
@@ -10,7 +10,7 @@ SQLite uses backtick quoting for identifiers to avoid conflicts with SQLite's ma
|
|
|
10
10
|
SELECT * FROM Books WHERE `Genre` = :Genre_w0;
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Table names are not quoted in the SQLite dialect
|
|
13
|
+
Table names are not quoted in the SQLite dialect -- they are used as plain identifiers.
|
|
14
14
|
|
|
15
15
|
## Named Parameters
|
|
16
16
|
|
|
@@ -49,7 +49,7 @@ SELECT COUNT(DISTINCT IDBook) AS RowCount FROM Books;
|
|
|
49
49
|
|
|
50
50
|
## Soft Delete
|
|
51
51
|
|
|
52
|
-
Works the same as other dialects
|
|
52
|
+
Works the same as other dialects -- when a `Deleted` column is present in the schema, Delete generates an UPDATE:
|
|
53
53
|
|
|
54
54
|
```sql
|
|
55
55
|
UPDATE Books SET `Deleted` = 1, `DeleteDate` = NOW(),
|
|
@@ -63,9 +63,9 @@ The `NOW()` calls are replaced with `datetime('now')` by the Meadow SQLite provi
|
|
|
63
63
|
|
|
64
64
|
When using the Meadow SQLite provider with `better-sqlite3`:
|
|
65
65
|
|
|
66
|
-
- **Boolean coercion**
|
|
67
|
-
- **Undefined coercion**
|
|
68
|
-
- **Synchronous execution**
|
|
66
|
+
- **Boolean coercion** -- `better-sqlite3` only accepts numbers, strings, bigints, buffers, and null. The provider automatically converts boolean values (`true`/`false`) to integers (`1`/`0`)
|
|
67
|
+
- **Undefined coercion** -- undefined values are converted to `null`
|
|
68
|
+
- **Synchronous execution** -- `better-sqlite3` is synchronous, but the Meadow provider wraps calls in an async-compatible callback pattern
|
|
69
69
|
|
|
70
70
|
## Query Overrides
|
|
71
71
|
|
package/docs/index.html
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
7
|
-
<meta name="description" content="Documentation
|
|
7
|
+
<meta name="description" content="FoxHound v2.0.26 Documentation — A Database Query generation library.">
|
|
8
8
|
|
|
9
|
-
<title>Documentation</title>
|
|
9
|
+
<title>FoxHound v2.0.26 Documentation</title>
|
|
10
10
|
|
|
11
11
|
<!-- Application Stylesheet -->
|
|
12
12
|
<link href="css/docuserve.css" rel="stylesheet">
|
package/docs/joins.md
CHANGED
|
@@ -94,8 +94,8 @@ Invalid joins are logged as warnings and silently skipped.
|
|
|
94
94
|
|
|
95
95
|
## Dialect Differences
|
|
96
96
|
|
|
97
|
-
- **MySQL**
|
|
98
|
-
- **MSSQL**
|
|
99
|
-
- **SQLite/ALASQL**
|
|
97
|
+
- **MySQL** -- `INNER JOIN Authors ON Authors.IDAuthor = Books.IDAuthor`
|
|
98
|
+
- **MSSQL** -- `INNER JOIN [Authors] ON Authors.IDAuthor = Books.IDAuthor`
|
|
99
|
+
- **SQLite/ALASQL** -- joins are supported in Read queries but not generated (the SQLite and ALASQL dialects do not include a `generateJoins` function; joins work through query overrides)
|
|
100
100
|
|
|
101
101
|
> **Note:** The SQLite and ALASQL dialects are primarily designed for simpler single-table queries. For complex join scenarios, consider using a query override or the MySQL/MSSQL dialect.
|