Socket
Socket
Sign inDemoInstall

@cap-js/db-service

Package Overview
Dependencies
Maintainers
2
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cap-js/db-service - npm Package Compare versions

Comparing version 1.0.0 to 1.0.1

9

CHANGELOG.md

@@ -7,4 +7,13 @@ # Change Log

## Version 1.0.1 - 2023-07-03
### Fixed
- Paths addressing a column of the query via `$self.<column>` in `group by` / `order by`, `having` or `where`
are now correctly substituted.
- Mapping for OData `average` function to ANSI SQL compliant `avg` function.
## Version 1.0.0 - 2023-06-23
- Initial Release

1

lib/cql-functions.js

@@ -6,2 +6,3 @@ const StandardFunctions = {

// length : (x) => `length(${x})`,
average: x => `avg(${x})`,
search: function (ref, arg) {

@@ -8,0 +9,0 @@ if (!('val' in arg)) throw `SQLite only supports single value arguments for $search`

@@ -278,3 +278,3 @@ 'use strict'

let wildcardSelect = false
const refs = []
const dollarSelfRefs = []
columns.forEach(col => {

@@ -298,3 +298,11 @@ if (col === '*') {

} else if (col.ref) {
refs.push(col)
const firstStepIsTableAlias =
(col.ref.length > 1 && col.ref[0] in sources) ||
// nested projection on table alias
(col.ref.length === 1 && col.ref[0] in sources && col.inline)
const firstStepIsSelf =
!firstStepIsTableAlias && col.ref.length > 1 && ['$self', '$projection'].includes(col.ref[0])
// we must handle $self references after the query elements have been calculated
if (firstStepIsSelf) dollarSelfRefs.push(col)
else handleRef(col)
} else if (col.expand) {

@@ -306,13 +314,5 @@ inferQueryElement(col)

})
refs.forEach(col => {
inferQueryElement(col)
const { definition } = col.$refLinks[col.$refLinks.length - 1]
if (col.cast)
// final type overwritten -> element not visible anymore
setElementOnColumns(col, getElementForCast(col))
else if ((col.ref.length === 1) & (col.ref[0] === '$user'))
// shortcut to $user.id
setElementOnColumns(col, queryElements[col.as || '$user'])
else setElementOnColumns(col, definition)
})
if (dollarSelfRefs.length) inferDollarSelfRefs(dollarSelfRefs)
if (wildcardSelect) inferElementsFromWildCard(aliases)

@@ -366,2 +366,50 @@ }

/**
* Processes references starting with `$self`, which are intended to target other query elements.
* These `$self` paths must be handled after processing the "regular" columns since they are dependent on other query elements.
*
* This function checks for `$self` references that may target other `$self` columns, and delays their processing.
* `$self` references not targeting other `$self` references are handled by the generic `handleRef` function immediately.
*
* @param {array} dollarSelfColumns - An array of column objects containing `$self` references.
*/
function inferDollarSelfRefs(dollarSelfColumns) {
do {
const unprocessedColumns = []
for (const currentDollarSelfColumn of dollarSelfColumns) {
const { ref } = currentDollarSelfColumn
const stepToFind = ref[1]
const referencesOtherDollarSelfColumn = dollarSelfColumns.find(
otherDollarSelfCol =>
otherDollarSelfCol !== currentDollarSelfColumn &&
(otherDollarSelfCol.as
? stepToFind === otherDollarSelfCol.as
: stepToFind === otherDollarSelfCol.ref?.[otherDollarSelfCol.ref.length - 1]),
)
if (referencesOtherDollarSelfColumn) {
unprocessedColumns.push(currentDollarSelfColumn)
} else {
handleRef(currentDollarSelfColumn)
}
}
dollarSelfColumns = unprocessedColumns
} while (dollarSelfColumns.length > 0)
}
function handleRef(col) {
inferQueryElement(col)
const { definition } = col.$refLinks[col.$refLinks.length - 1]
if (col.cast)
// final type overwritten -> element not visible anymore
setElementOnColumns(col, getElementForCast(col))
else if ((col.ref.length === 1) & (col.ref[0] === '$user'))
// shortcut to $user.id
setElementOnColumns(col, queryElements[col.as || '$user'])
else setElementOnColumns(col, definition)
}
/**
* This function is responsible for inferring a query element based on a provided column.

@@ -484,3 +532,13 @@ * It initializes and attaches a non-enumerable `$refLinks` property to the column,

const elements = definition.elements || definition._target?.elements
if (elements && id in elements) {
const element = elements?.[id]
if (firstStepIsSelf && element?.isAssociation) {
throw cds.error(
`Paths starting with “$self” must not contain steps of type “cds.Association”: ref: [ ${column.ref.map(
idOnly,
)} ]`,
)
}
if (element) {
const $refLink = { definition: elements[id], target: column.$refLinks[i - 1].target }

@@ -512,3 +570,5 @@ column.$refLinks.push($refLink)

else if (skipAliasedFkSegmentsOfNameStack[0] === id) skipAliasedFkSegmentsOfNameStack.shift()
else nameSegments.push(id)
else {
nameSegments.push(firstStepIsSelf && i === 1 ? element.__proto__.name : id)
}
}

@@ -595,3 +655,3 @@

// check if we need to merge the column `ref` into the join tree of the query
if (!inExists && !virtual && isColumnJoinRelevant(column)) {
if (!inExists && !virtual && isColumnJoinRelevant(column, firstStepIsSelf)) {
Object.defineProperty(column, 'isJoinRelevant', { value: true })

@@ -770,3 +830,3 @@ joinTree.mergeColumn(column)

if (fkAccess) return false
else return true
return true
}

@@ -773,0 +833,0 @@

2

package.json
{
"name": "@cap-js/db-service",
"version": "1.0.0",
"version": "1.0.1",
"description": "CDS base database service",

@@ -5,0 +5,0 @@ "homepage": "https://cap.cloud.sap/",

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc