squirreling 0.2.0 → 0.2.2
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 +2 -1
- package/package.json +3 -3
- package/src/execute/execute.js +6 -5
- package/src/execute/having.js +5 -3
- package/src/index.d.ts +6 -5
- package/src/types.d.ts +1 -1
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
[](https://www.npmjs.com/package/squirreling)
|
|
8
8
|
[](https://github.com/hyparam/squirreling/actions)
|
|
9
9
|
[](https://opensource.org/licenses/MIT)
|
|
10
|
+

|
|
10
11
|
[](https://www.npmjs.com/package/squirreling?activeTab=dependencies)
|
|
11
12
|
|
|
12
13
|
Squirreling is a lightweight SQL engine for JavaScript applications, designed to provide efficient and easy-to-use database functionalities in the browser.
|
|
@@ -29,7 +30,7 @@ const source = [
|
|
|
29
30
|
{ id: 2, name: 'Bob' },
|
|
30
31
|
]
|
|
31
32
|
|
|
32
|
-
const result = executeSql({ source,
|
|
33
|
+
const result = executeSql({ source, query: 'SELECT UPPER(name) AS name_upper FROM users' })
|
|
33
34
|
console.log(result)
|
|
34
35
|
// Output: [ { name_upper: 'ALICE' }, { name_upper: 'BOB' } ]
|
|
35
36
|
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "squirreling",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Squirreling SQL Engine",
|
|
5
5
|
"author": "Hyperparam",
|
|
6
6
|
"homepage": "https://hyperparam.app",
|
|
7
7
|
"keywords": [
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@types/node": "24.10.1",
|
|
41
41
|
"@vitest/coverage-v8": "4.0.13",
|
|
42
42
|
"eslint": "9.39.1",
|
|
43
|
-
"eslint-plugin-jsdoc": "61.4.
|
|
43
|
+
"eslint-plugin-jsdoc": "61.4.1",
|
|
44
44
|
"typescript": "5.9.3",
|
|
45
45
|
"vitest": "4.0.13"
|
|
46
46
|
}
|
package/src/execute/execute.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { defaultAggregateAlias, evaluateAggregate } from './aggregates.js'
|
|
6
6
|
import { evaluateExpr } from './expression.js'
|
|
7
|
-
import {
|
|
7
|
+
import { evaluateHavingExpr } from './having.js'
|
|
8
8
|
import { parseSql } from '../parse/parse.js'
|
|
9
9
|
import { createMemorySource, createRowAccessor } from '../backend/memory.js'
|
|
10
10
|
|
|
@@ -14,8 +14,8 @@ import { createMemorySource, createRowAccessor } from '../backend/memory.js'
|
|
|
14
14
|
* @param {ExecuteSqlOptions} options - the execution options
|
|
15
15
|
* @returns {Record<string, any>[]} the result rows matching the query
|
|
16
16
|
*/
|
|
17
|
-
export function executeSql({ source,
|
|
18
|
-
const select = parseSql(
|
|
17
|
+
export function executeSql({ source, query }) {
|
|
18
|
+
const select = parseSql(query)
|
|
19
19
|
const dataSource = Array.isArray(source) ? createMemorySource(source) : source
|
|
20
20
|
return evaluateSelectAst(select, dataSource)
|
|
21
21
|
}
|
|
@@ -142,6 +142,8 @@ function evaluateSelectAst(select, dataSource) {
|
|
|
142
142
|
throw new Error('JOIN is not supported')
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
// SQL priority: from, where, group by, having, select, order by, offset, limit
|
|
146
|
+
|
|
145
147
|
// WHERE clause filtering
|
|
146
148
|
/** @type {RowSource[]} */
|
|
147
149
|
const working = []
|
|
@@ -244,8 +246,7 @@ function evaluateSelectAst(select, dataSource) {
|
|
|
244
246
|
if (select.having) {
|
|
245
247
|
// For HAVING, we need to evaluate aggregates in the context of the group
|
|
246
248
|
// Create a special row context that includes both the group data and aggregate values
|
|
247
|
-
|
|
248
|
-
if (!evaluateHavingExpr(select.having, havingContext, group)) {
|
|
249
|
+
if (!evaluateHavingExpr(select.having, resultRow, group)) {
|
|
249
250
|
continue
|
|
250
251
|
}
|
|
251
252
|
}
|
package/src/execute/having.js
CHANGED
|
@@ -12,7 +12,7 @@ import { evaluateExpr } from './expression.js'
|
|
|
12
12
|
* @param {RowSource[]} group - the group of rows
|
|
13
13
|
* @returns {RowSource} a context row for HAVING evaluation
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
function createHavingContext(resultRow, group) {
|
|
16
16
|
// Include the first row of the group (for GROUP BY columns)
|
|
17
17
|
const firstRow = group[0]
|
|
18
18
|
/** @type {Record<string, any>} */
|
|
@@ -41,11 +41,13 @@ export function createHavingContext(resultRow, group) {
|
|
|
41
41
|
* Evaluates a HAVING expression with support for aggregate functions
|
|
42
42
|
*
|
|
43
43
|
* @param {ExprNode} expr - the HAVING expression
|
|
44
|
-
* @param {
|
|
44
|
+
* @param {Record<string, any>} row - the aggregated result row
|
|
45
45
|
* @param {RowSource[]} group - the group of rows for re-evaluating aggregates
|
|
46
46
|
* @returns {boolean} whether the HAVING condition is satisfied
|
|
47
47
|
*/
|
|
48
|
-
export function evaluateHavingExpr(expr,
|
|
48
|
+
export function evaluateHavingExpr(expr, row, group) {
|
|
49
|
+
const context = createHavingContext(row, group)
|
|
50
|
+
|
|
49
51
|
// For HAVING, we need special handling of aggregate functions
|
|
50
52
|
// They need to be re-evaluated against the group
|
|
51
53
|
if (expr.type === 'function') {
|
package/src/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ExecuteSqlOptions, SelectStatement } from './types.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Executes a SQL SELECT query against an array of data rows
|
|
5
5
|
*
|
|
6
|
-
* @param
|
|
7
|
-
* @param
|
|
6
|
+
* @param options
|
|
7
|
+
* @param options.source - source data as a list of objects or a DataSource
|
|
8
|
+
* @param options.sql - SQL query string
|
|
8
9
|
* @returns rows matching the query
|
|
9
10
|
*/
|
|
10
|
-
export function executeSql(
|
|
11
|
+
export function executeSql(options: ExecuteSqlOptions): Record<string, any>[]
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Parses a SQL query string into an abstract syntax tree
|
|
@@ -15,4 +16,4 @@ export function executeSql(rows: RowSource[], sql: string): RowSource[]
|
|
|
15
16
|
* @param sql - SQL query string to parse
|
|
16
17
|
* @returns parsed SQL select statement
|
|
17
18
|
*/
|
|
18
|
-
export function parseSql(
|
|
19
|
+
export function parseSql(query: string): SelectStatement
|
package/src/types.d.ts
CHANGED