@mlagie/sql-connector 2.0.4 → 2.0.5
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.
|
@@ -9,6 +9,7 @@ on:
|
|
|
9
9
|
pull_request:
|
|
10
10
|
branches:
|
|
11
11
|
- main
|
|
12
|
+
workflow_dispatch:
|
|
12
13
|
jobs:
|
|
13
14
|
check_security:
|
|
14
15
|
runs-on: ubuntu-latest
|
|
@@ -48,7 +49,7 @@ jobs:
|
|
|
48
49
|
needs:
|
|
49
50
|
- check_security
|
|
50
51
|
- integrity
|
|
51
|
-
if: github.event_name == 'release'
|
|
52
|
+
if: github.event_name == 'release' || github.ref_name == 'main'
|
|
52
53
|
runs-on: ubuntu-latest
|
|
53
54
|
environment: sqlc
|
|
54
55
|
permissions:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mlagie/sql-connector",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "Le module sql-connector permet de gérer les connexions à une base de données MySQL, de définir des schémas de tables, et d'interagir avec les données de manière simple et efficace.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Release v2.0.5 — Aggregation Engine Expansion (COUNT, DISTINCT & Group Matrix Resolution)
|
|
2
|
+
|
|
3
|
+
This release expands the dynamic query builder capability to support structured multi-row statistical analysis (`COUNT` and `DISTINCT`) while maintaining full architectural alignment with our strict SQL Safety parameters.
|
|
4
|
+
|
|
5
|
+
## What Was Improved
|
|
6
|
+
|
|
7
|
+
- **Native Secure** `COUNT` `Aggregation Matrix`: Introduced the structured `{ count: "*" }` or `{ count: "column_name" }` block into `utils/buildQuery.js`. This allows developers to safely generate standard SQL COUNT() aggregations without raw string shortcuts triggering safety breaches in escapeIdentifier().
|
|
8
|
+
|
|
9
|
+
- **Distinct Value Interception Support**: Optimized fields evaluation layout to support `DISTINCT` processing inside column mappings and `GROUP BY` structural nodes, resolving compatibility limits under aggressive `ONLY_FULL_GROUP_BY` database runtime settings.
|
|
10
|
+
|
|
11
|
+
- `Granular Regression Controls`: Hardened testing architecture with direct atomic assertions on nested selection objects to ensure utility stability over complex ingestion flows.
|
|
12
|
+
|
|
13
|
+
## **Unit Test Additions** (`tests/buildQuery.test.js`)
|
|
14
|
+
|
|
15
|
+
To ensure functional continuity, the selection building block test matrix has been expanded with the following scenarios:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
describe('buildQuery - Advanced Fields & Aggregations', () => {
|
|
19
|
+
|
|
20
|
+
test('Should safely compile COUNT(*) aggregated calculations with an expression alias', () => {
|
|
21
|
+
const fields = [{ count: '*', as: 'total_user' }];
|
|
22
|
+
expect(buildSelect(fields)).toBe('COUNT(*) AS `total_user`');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('Should safely compile COUNT(column) on structured column identifiers', () => {
|
|
26
|
+
const fields = [{ count: 'id', as: 'unique_ids' }];
|
|
27
|
+
expect(buildSelect(fields)).toBe('COUNT(`id`) AS `unique_ids`');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('Should correctly process multi-column GROUP BY arrays to avoid ONLY_FULL_GROUP_BY validation issues', () => {
|
|
31
|
+
const options = {
|
|
32
|
+
select: ['status', 'email', { count: '*', as: 'total_user' }],
|
|
33
|
+
groupBy: ['status', 'email']
|
|
34
|
+
};
|
|
35
|
+
const parts = buildQueryParts(options);
|
|
36
|
+
|
|
37
|
+
expect(parts).toContain('GROUP BY `status`, `email`');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Component Impact
|
|
43
|
+
|
|
44
|
+
| Impacted Area | Description | Status |
|
|
45
|
+
|------------------------------|-------------------------------------------------------------------------------------------------------------------------|--------------|
|
|
46
|
+
| **buildQuery.js** | Added `field.count` mapping to isolate raw expressions (`*`) safely from structural identifiers formatting. | **Upgraded** |
|
|
47
|
+
| **tests/buildQuery.test.js** | Integrated targeted coverage checking for isolated function behaviors and multi-field groups. | **Covered** |
|
|
48
|
+
| **Data Ingestion Modules** | Safely resolving analytical aggregations (like cross-team platform data pipeline counters) in single-trip transactions. | **Resolved** |
|
|
49
|
+
|
|
50
|
+
## Usage Example (Analytics Ingestion)
|
|
51
|
+
|
|
52
|
+
Instead of passing unstable raw operations, leverage the new token syntax in your models:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
const teamNameData = await ProjectPipeline.find({
|
|
56
|
+
select: [
|
|
57
|
+
"team",
|
|
58
|
+
"source",
|
|
59
|
+
{ count: "*", as: "total_pipelines" } // Raw counting handled securely
|
|
60
|
+
],
|
|
61
|
+
groupBy: ["team", "source"] // Aligned with database safety policies
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
*This release is fully covered by our automated CI/CD pipeline verification gates. Run npm update `@mlagie/sql-connector` to align your staging environments.*
|
package/src/utils/buildQuery.js
CHANGED
|
@@ -37,6 +37,10 @@ function buildField(field) {
|
|
|
37
37
|
}
|
|
38
38
|
else if (field.col)
|
|
39
39
|
sql = escapeIdentifier(field.col);
|
|
40
|
+
else if (field.distinct)
|
|
41
|
+
sql = `DISTINCT ${escapeIdentifier(field.distinct)}`;
|
|
42
|
+
else if (field.count)
|
|
43
|
+
sql = `COUNT(${escapeIdentifier(field.count)})`;
|
|
40
44
|
|
|
41
45
|
if (field.as)
|
|
42
46
|
sql += ` AS ${escapeIdentifier(field.as)}`;
|
package/tests/buildQuery.test.js
CHANGED
|
@@ -76,4 +76,27 @@ describe('Utils - buildQuery.js', () => {
|
|
|
76
76
|
expect(() => buildQueryParts({ limit: 'abc' })).toThrow('Invalid LIMIT value');
|
|
77
77
|
});
|
|
78
78
|
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('buildQuery - Advanced Fields & Aggregations', () => {
|
|
82
|
+
|
|
83
|
+
test('Should safely compile COUNT(*) aggregated calculations with an expression alias', () => {
|
|
84
|
+
const fields = [{ count: '*', as: 'total_user' }];
|
|
85
|
+
expect(buildSelect(fields)).toBe('COUNT(*) AS `total_user`');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('Should safely compile COUNT(column) on structured column identifiers', () => {
|
|
89
|
+
const fields = [{ count: 'id', as: 'unique_ids' }];
|
|
90
|
+
expect(buildSelect(fields)).toBe('COUNT(`id`) AS `unique_ids`');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('Should correctly process multi-column GROUP BY arrays to avoid ONLY_FULL_GROUP_BY validation issues', () => {
|
|
94
|
+
const options = {
|
|
95
|
+
select: ['status', 'email', { count: '*', as: 'total_user' }],
|
|
96
|
+
groupBy: ['status', 'email']
|
|
97
|
+
};
|
|
98
|
+
const parts = buildQueryParts(options);
|
|
99
|
+
|
|
100
|
+
expect(parts).toContain('GROUP BY `status`, `email`');
|
|
101
|
+
});
|
|
79
102
|
});
|