Socket
Socket
Sign inDemoInstall

@sap/cds-sqlite

Package Overview
Dependencies
Maintainers
3
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sap/cds-sqlite - npm Package Compare versions

Comparing version 1.11.1 to 1.24.0

lib/client/TenantManager.js

121

CHANGELOG.md

@@ -9,2 +9,123 @@ # Changelog

## Version 1.24.0 - 2020-03-19
### Added
- Single timestamp per transaction
- default timeout 5s for acquiring client from pool
### Changed
- deleted concat handling (done in cds-sql)
## Version 1.23.1 - 2020-02-26
### Removed
- `npm-shrinkwrap.json`
## Version 1.23.0 - 2020-02-19
### Changed
- Updated version of @sap/cds-sql to 1.23.0
## Version 1.22.0 - 2020-02-05
### Added
- Allow setting the [journal mode](https://www.sqlite.org/draft/pragma.html#pragma_journal_mode) via credentials.journalMode
### Changed
- Pool options can once again be overwritten
## Version 1.21.0 - 2019-12-10
### Changed
- Pool options always set to default
## Version 1.20.1 - 2019-11-29
### Changed
- Updated version of @sap/cds-sql to 1.20.1
## Version 1.20.0 - 2019-11-19
### Added
- Conversion of hana's `seconds_between` function to `strftime` for sqlite
## Version 1.19.1 - 2019-10-30
### Changed
- Updated version of @sap/cds-sql to 1.19.1
## Version 1.19.0 - 2019-10-29
### Removed
- `npm-shrinkwrap.json`
## Version 1.18.1 - 2019-10-16
### Changed
- Updated version of @sap/cds-sql to 1.18.1
## Version 1.18.0 - 2019-10-02
### Changed
- Updated version of @sap/cds-sql to 1.18.0
## Version 1.17.1 - 2019-09-18
### Changed
- Updated version of @sap/cds-sql to 1.17.1
## Version 1.17.0 - 2019-09-09
### Added
- Streaming into sqlite
## Version 1.16.0 - 2019-08-21
### Changed
- Signature of the Client's constructor
## Version 1.15.0 - 2019-07-23
### Added
- Support multi tenancy for file based database
### Fixed
- Streaming supports `null` values
## Version 1.14.0 - 2019-07-09
### Added
- Named binding parameters
- Support files as db in tenant manager
## Version 1.13.0 - 2019-06-24
### Changed
- Updated version of @sap/cds-sql to 1.13.0
## Version 1.12.0 - 2019-05-24
### Changed
- Updated version of @sap/cds-sql to 1.12.0
## Version 1.11.1 - 2019-05-16

@@ -11,0 +132,0 @@

24

lib/cds.js
const injection = {
inject (cds) {
if (!cds || typeof cds !== 'object') {
throw new Error('Injected value is not of type `cds`')
cds: global.cds,
inject (cds, force = false) {
if (force || !injection.cds) {
if (!cds || typeof cds !== 'object') {
throw new Error('Injected value is not of type `cds`')
}
injection.cds = cds
}
injection.cds = cds
require('@sap/cds-sql').inject(cds)
require('@sap/cds-sql').inject(injection.cds, force)
}

@@ -21,10 +24,3 @@ }

if (!injection.cds) {
if (name === 'config') {
return { data: {} }
}
throw new Error('This method requires `cds` to be injected')
}
if (name === 'config' && !target.cds.config) {
if (name === 'config' && (!target.cds || !target.cds.config)) {
return { data: {} }

@@ -31,0 +27,0 @@ }

@@ -7,3 +7,2 @@ const { Database } = require('sqlite3')

BaseClient,
errors: { IllegalFunctionArgumentError, InconsistentClientError },
builder: { sqlFactory },

@@ -36,6 +35,7 @@ expand: { createJoinCQNFromExpanded, hasExpand, rawToExpanded },

*
* @param {Object} credentials - Connection details.
* @param {string} credentials.database - Filename to the database or :memory; for in memory
* @param {Object} options - Connection details.
* @param {Object} options.credentials - Connection details.
* @param {string} options.credentials.database - Filename to the database or :memory; for in memory
*/
constructor (credentials) {
constructor ({ credentials }) {
super([

@@ -65,3 +65,3 @@ ['cds.Boolean', convertToBoolean],

if (!this._credentials) {
return reject(new IllegalFunctionArgumentError('options.credentials'))
return reject(new Error('Cannot connect to database. No connection credentials provided.'))
}

@@ -74,3 +74,11 @@

resolve(this)
if (this._credentials.journalMode) {
this.execute(`PRAGMA journal_mode=${this._credentials.journalMode.toUpperCase()}`)
.then(() => {
resolve(this)
})
.catch(reject)
} else {
resolve(this)
}
})

@@ -133,7 +141,7 @@ })

if (this._toBeDestroyed) {
return reject(new InconsistentClientError())
return reject(new Error('Client is in an inconsistent state'))
}
if (!Array.isArray(values)) {
return reject(new IllegalFunctionArgumentError('values'))
if (!Array.isArray(values) && (typeof query !== 'string' || typeof values !== 'object')) {
return reject(new Error(`Cannot execute SQL statement. Invalid values provided: ${JSON.stringify(values)}`))
}

@@ -185,3 +193,3 @@

if (!query.SELECT && (typeof query !== 'string' || !query.trim().startsWith('SELECT'))) {
throw new IllegalFunctionArgumentError('query')
throw new Error(`Cannot stream from sqlite. Invalid query provided: ${JSON.stringify(query)}`)
}

@@ -195,10 +203,11 @@

const stream_ = new Readable()
const val = Object.values(resultSet[0])[0]
let val = Object.values(resultSet[0])[0]
if (val === null) {
return null
}
if (typeof val === 'number') {
return
val = val.toString()
}
const stream_ = new Readable()
stream_.push(val)

@@ -209,3 +218,2 @@ stream_.push(null)

}
_returnFirstResultIfOne (isOne, result) {

@@ -218,3 +226,2 @@ if (isOne) {

}
_execute (cqn, inValues = []) {

@@ -227,3 +234,3 @@ const { sql, values = [] } = sqlFactory(

customBuilder: CustomBuilder,
now: { sql: "strftime('%Y-%m-%dT%H:%M:%SZ','now')" } // '2012-12-03T07:16:23Z'
now: this._transactionTimestamp || { sql: "strftime('%Y-%m-%dT%H:%M:%fZ','now')" } // '2012-12-03T07:16:23.574Z'
},

@@ -234,8 +241,10 @@ this._csn

return this._executeSQL(
sql,
outValues,
cqn.SELECT && cqn.SELECT.one,
getPostProcessMapper(this._toService, this._csn, cqn)
)
return this._streamValues(cqn, outValues).then(() => {
return this._executeSQL(
sql,
outValues,
cqn.SELECT && cqn.SELECT.one,
getPostProcessMapper(this._toService, this._csn, cqn)
)
})
}

@@ -253,3 +262,8 @@

_executeSQL (sql, values, isOne, postMapper) {
if (this._isStatementType('select', sql)) {
// support named binding parameters
if (values && typeof values === 'object' && !Array.isArray(values)) {
values = this._getValuesProxy(values)
}
if (this._isStatementType('select', sql) || this._isStatementType('pragma', sql)) {
return this._executeSelect(sql, values, isOne, postMapper)

@@ -266,2 +280,22 @@ }

_getValuesProxy (values) {
return new Proxy(values, {
getOwnPropertyDescriptor: (obj, prop) => {
if (prop.length > 1 && prop.startsWith(':')) {
return Object.getOwnPropertyDescriptor(obj, prop.slice(1))
}
return Object.getOwnPropertyDescriptor(obj, prop)
},
get: (obj, prop) => {
if (prop.length > 1 && prop.startsWith(':')) {
return obj[prop.slice(1)]
}
return obj[prop]
},
ownKeys: target => {
return Reflect.ownKeys(target).map(key => `:${key}`)
}
})
}
_isStatementType (type, sql) {

@@ -277,3 +311,3 @@ // Regex is faster than toLower + trim + startsWith

if (err) {
err.failedQuery = sql
err.query = sql
return reject(err)

@@ -291,3 +325,3 @@ }

if (err) {
err.failedQuery = sql
err.query = sql
return reject(err)

@@ -345,3 +379,6 @@ }

const { sql, values } = sqlFactory(cqn, { customBuilder: CustomBuilder })
const { sql, values } = sqlFactory(cqn, {
now: this._transactionTimestamp || { sql: "strftime('%Y-%m-%dT%H:%M:%fZ','now')" },
customBuilder: CustomBuilder
})
queries.push(this._executeSelect(sql, values, false))

@@ -369,10 +406,38 @@ }

/* istanbul ignore next */
return selectDeepUpdateData(this._csn && this._csn.definitions, cqn, this._execute.bind(this)).then(selectData => {
return this.processNestedCQNs(
createDeepUpdateCQNs(this._csn && this._csn.definitions, cqn, selectData),
this._execute.bind(this)
)
return selectDeepUpdateData(this._csn && this._csn.definitions, cqn, this._execute.bind(this), this._context).then(
selectData => {
return this.processNestedCQNs(
createDeepUpdateCQNs(this._csn && this._csn.definitions, cqn, selectData),
this._execute.bind(this)
)
}
)
}
_stream2Buffer (stream) {
return new Promise(resolve => {
const buffer = []
stream.on('data', chunk => {
buffer.push(chunk)
})
stream.on('end', () => {
resolve(Buffer.concat(buffer))
})
stream.on('error', () => {
stream.removeAllListeners('error')
stream.push(null)
})
})
}
async _streamValues (cqn, values) {
if (cqn.UPDATE || cqn.INSERT) {
for (let i = 0; i < values.length; i++) {
if (values[i] && typeof values[i].pipe === 'function') {
values[i] = await this._stream2Buffer(values[i])
}
}
}
}
/**

@@ -390,3 +455,3 @@ * Prepare SQL statement.

if (err) {
err.failedQuery = sql
err.query = sql
return reject(err)

@@ -393,0 +458,0 @@ }

@@ -1,6 +0,8 @@

const { errors: { IllegalFunctionArgumentError } } = require('@sap/cds-sql')
const _validateFails = option => {
throw new Error(`Invalid database option: ${option}`)
}
const _validateDatabase = database => {
if (!database) {
throw new IllegalFunctionArgumentError('options.credentials.database')
_validateFails('no "options.credentials.database" provided')
}

@@ -10,4 +12,4 @@ }

const _validatePool = options => {
if (options.pool.min > options.pool.max) {
throw new IllegalFunctionArgumentError('options.pool.min')
if (!isNaN(options.pool.min) && !isNaN(options.pool.max) && options.pool.min > options.pool.max) {
_validateFails('"options.pool.min" is bigger than "options.pool.max"')
}

@@ -17,11 +19,11 @@

if (options.pool.max !== 1) {
throw new IllegalFunctionArgumentError('options.pool.max')
_validateFails('"options.pool.max" in :memory: should equal 1')
}
if (options.pool.evictionRunIntervalMillis !== 0) {
throw new IllegalFunctionArgumentError('options.pool.evictionRunIntervalMillis')
_validateFails('"options.pool.evictionRunIntervalMillis" in :memory: should equal 0')
}
if (options.pool.idleTimeoutMillisForPools !== 0) {
throw new IllegalFunctionArgumentError('options.pool.idleTimeoutMillisForPools')
_validateFails('"options.pool.idleTimeoutMillisForPools" in :memory: should equal 0')
}

@@ -31,2 +33,11 @@ }

const _validateJournalMode = mode => {
// https://www.sqlite.org/draft/pragma.html#pragma_journal_mode
const allowed = ['DELETE', 'TRUNCATE', 'PERSIST', 'MEMORY', 'WAL', 'OFF']
if (mode && !allowed.includes(mode.toUpperCase())) {
_validateFails(`journalMode "${mode}" is not one of "${allowed.join(', ')}"`)
}
}
/**

@@ -37,2 +48,3 @@ * Validates the connect and pool options and adds defaults if not given.

* @param {Object} [options.credentials.database] - Alias for url.
* @param {string} [options.credentials.journalMode] - SQLite PRAGMA journal mode as a string.
* @param {Object} [options.pool] - The min and max pool options.

@@ -43,16 +55,20 @@ * @param {number} [options.pool.min] - The minimum number of db connection clients.

* @param {number} [options.pool.idleTimeoutMillisForPools] - The time interval in ms until an idle pool is evicted.
* @throws {IllegalFunctionArgumentError}
* @throws Error if one of the options is invalid or missing
*/
const options = options => {
options.credentials = options.credentials || {}
options.credentials.database = options.credentials.database || options.database || options.host || options.url
options.credentials.database =
options.credentials.database || options.database || options.host || options.url || options.credentials.url
options.pool.min = options.pool.min || 1
options.pool.max = options.pool.max || (options.credentials.database === ':memory:' ? 1 : 10)
options.pool.evictionRunIntervalMillis =
options.pool.evictionRunIntervalMillis || (options.credentials.database === ':memory:' ? 0 : 10000)
options.pool.idleTimeoutMillisForPools =
options.pool.idleTimeoutMillisForPools || (options.credentials.database === ':memory:' ? 0 : 60000)
options.pool.max = options.pool.max || 1
options.pool.evictionRunIntervalMillis = options.pool.evictionRunIntervalMillis || 0
options.pool.idleTimeoutMillisForPools = options.pool.idleTimeoutMillisForPools || 0
if (!('acquireTimeoutMillis' in options.pool)) {
options.pool.acquireTimeoutMillis = 5000
}
_validateDatabase(options.credentials.database)
_validateJournalMode(options.credentials.journalMode)
_validatePool(options)

@@ -59,0 +75,0 @@ }

@@ -40,10 +40,8 @@ const FunctionBuilder = require('@sap/cds-sql').builder.FunctionBuilder

if (functionName === 'concat') {
this._concatFunction(args)
} else if (dateTimeFunctions.has(functionName)) {
if (dateTimeFunctions.has(functionName)) {
this._timeFunction(functionName, args)
} else if (functionName.includes('contains')) {
this._handleContains(args)
} else if (standadFunctions.includes(functionName)) {
this._standardFunction(functionName, args)
} else if (functionName === 'seconds_between') {
this._secondsBetweenFunction(args)
} else {

@@ -54,56 +52,2 @@ super._handleFunction()

_concatFunction (args) {
const res = []
for (const arg of args) {
if (arg.ref) {
const { sql, values } = new this.ReferenceBuilder(arg, this._options, this._csn).build()
res.push(sql)
this._outputObj.values.push(...values)
} else if (arg.val) {
this._outputObj.values.push(arg.val)
res.push(this._options.placeholder)
}
}
this._outputObj.sql.push('(')
this._outputObj.sql.push(res.join(' || '))
this._outputObj.sql.push(')')
}
_handleContains (args) {
const contains = this._obj.func
? !this._obj.func.toLowerCase().includes('not')
: !this._obj.ref[0].toLowerCase().includes('not')
const columns = this._columns(args)
const params = this._obj.func ? args.slice(1, args.length - 1) : this._obj.ref[1].args.slice(1, args.length - 1)
for (const param of params) {
if (param === 'or' || param === 'and' || param === 'not') {
this._outputObj.sql.push(param)
} else {
const searchText = param.val.toLowerCase()
this._outputObj.sql.push('(')
this._createLikeComparison(contains, columns, searchText)
this._outputObj.sql.push(')')
}
}
}
_createLikeComparison (contains, columns, searchText) {
const length = columns.length
for (let i = 0; i < length; i++) {
if (columns[i].ref) {
const { sql } = new this.ReferenceBuilder(columns[i], this._options, this._csn).build()
this._outputObj.sql.push('lower', '(', sql, ')', contains ? 'LIKE' : 'NOT LIKE', '?')
this._outputObj.values.push(`%${searchText.replace(/(_|%)/g, '\\$1')}%`)
if (i !== columns.length - 1 && columns[i + 1] !== ')') {
this._outputObj.sql.push(contains ? 'OR' : 'AND')
}
}
}
}
_columns (args) {
return args[0].xpr || args[0].list || [args[0]]
}
_standardFunction (functionName, args) {

@@ -136,2 +80,29 @@ switch (functionName) {

_val (val) {
this._outputObj.sql.push('?')
this._outputObj.values.push(val)
}
_ref (ref) {
this._outputObj.sql.push(new this.ReferenceBuilder(ref, this._options, this._csn).build().sql)
}
_secondsBetweenFunction (args) {
this._outputObj.sql.push('strftime(?,')
this._outputObj.values.push('%s')
if (args[1].val) {
this._val(args[1].val)
} else {
this._ref(args[1])
}
this._outputObj.sql.push(') - strftime(?,')
this._outputObj.values.push('%s')
if (args[0].val) {
this._val(args[0].val)
} else {
this._ref(args[0])
}
this._outputObj.sql.push(')')
}
_timeFunction (functionName, args) {

@@ -138,0 +109,0 @@ this._outputObj.sql.push('strftime(')

@@ -24,4 +24,6 @@ const SelectBuilder = require('@sap/cds-sql').builder.SelectBuilder

}
_forUpdate () {}
}
module.exports = CustomSelectBuilder

@@ -22,2 +22,7 @@ const dependencies = {

},
get TenantManager () {
const TenantManager = require('./client/TenantManager')
Object.defineProperty(dependencies, 'TenantManager', { value: TenantManager })
return TenantManager
},
inject: (...args) => {

@@ -24,0 +29,0 @@ return require('./cds').inject(...args)

const {
errors: { IllegalFunctionArgumentError },
thenable: { all, reject }

@@ -42,3 +41,3 @@ } = require('@sap/cds-sql')

return reject(new IllegalFunctionArgumentError('values'))
return reject(new Error(`Cannot execute SQL statement. Invalid values provided: ${JSON.stringify(values)}`))
}

@@ -45,0 +44,0 @@

@@ -1,1 +0,1 @@

{"bundleDependencies":false,"dependencies":{"@sap/cds-sql":"1.11.1"},"deprecated":false,"description":"Driver package for access to sqlite database, including setting up the client, configuring all the necessary options to initiate the connection and handling database specifics so that they can be processed on our end.","engines":{"node":">= 8.9.0"},"husky":{"hooks":{"pre-commit":"lint-staged"}},"lint-staged":{"{lib,test}/**/*.js":["prettier-standard","standard --fix","git add"]},"main":"lib/index.js","name":"@sap/cds-sqlite","version":"1.11.1","license":"SEE LICENSE IN developer-license-3.1.txt"}
{"bundleDependencies":false,"dependencies":{"@sap/cds-sql":"^1.24.0"},"deprecated":false,"description":"Driver package for access to sqlite database, including setting up the client, configuring all the necessary options to initiate the connection and handling database specifics so that they can be processed on our end.","engines":{"node":">= 8.9.0"},"husky":{"hooks":{"pre-commit":"lint-staged"}},"lint-staged":{"{lib,test}/**/*.js":["prettier-standard","standard --fix","git add"]},"main":"lib/index.js","name":"@sap/cds-sqlite","version":"1.24.0","license":"SEE LICENSE IN developer-license-3.1.txt"}

Sorry, the diff of this file is not supported yet

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