@cap-js/sqlite 1.7.7 → 1.8.0
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/CHANGELOG.md +14 -0
- package/lib/SQLiteService.js +25 -17
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@
|
|
|
4
4
|
- The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
5
5
|
- This project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [1.8.0](https://github.com/cap-js/cds-dbs/compare/sqlite-v1.7.8...sqlite-v1.8.0) (2025-01-28)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
* support for cds.Map ([#889](https://github.com/cap-js/cds-dbs/issues/889)) ([cde7514](https://github.com/cap-js/cds-dbs/commit/cde7514df20396383e0179ffce838596e3706bb2))
|
|
13
|
+
|
|
14
|
+
## [1.7.8](https://github.com/cap-js/cds-dbs/compare/sqlite-v1.7.7...sqlite-v1.7.8) (2024-12-16)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
* default `[development]` URL to `:memory:` ([#926](https://github.com/cap-js/cds-dbs/issues/926)) ([51e8aa7](https://github.com/cap-js/cds-dbs/commit/51e8aa70868a78594626ba19c02ff495571e751f))
|
|
20
|
+
|
|
7
21
|
## [1.7.7](https://github.com/cap-js/cds-dbs/compare/sqlite-v1.7.6...sqlite-v1.7.7) (2024-11-14)
|
|
8
22
|
|
|
9
23
|
|
package/lib/SQLiteService.js
CHANGED
|
@@ -5,6 +5,7 @@ const $session = Symbol('dbc.session')
|
|
|
5
5
|
const convStrm = require('stream/consumers')
|
|
6
6
|
const { Readable } = require('stream')
|
|
7
7
|
|
|
8
|
+
const SANITIZE_VALUES = process.env.NODE_ENV === 'production' && cds.env.log.sanitize_values !== false
|
|
8
9
|
const keywords = cds.compiler.to.sql.sqlite.keywords
|
|
9
10
|
// keywords come as array
|
|
10
11
|
const sqliteKeywords = keywords.reduce((prev, curr) => {
|
|
@@ -12,10 +13,17 @@ const sqliteKeywords = keywords.reduce((prev, curr) => {
|
|
|
12
13
|
return prev
|
|
13
14
|
}, {})
|
|
14
15
|
|
|
16
|
+
// define date and time functions in js to allow for throwing errors
|
|
17
|
+
const isTime = /^\d{1,2}:\d{1,2}:\d{1,2}$/
|
|
18
|
+
const hasTimezone = /([+-]\d{1,2}:?\d{0,2}|Z)$/
|
|
19
|
+
const toDate = (d, allowTime = false) => {
|
|
20
|
+
const date = new Date(allowTime && isTime.test(d) ? `1970-01-01T${d}Z` : hasTimezone.test(d) ? d : d + 'Z')
|
|
21
|
+
if (Number.isNaN(date.getTime())) throw new Error(`Value does not contain a valid ${allowTime ? 'time' : 'date'} "${d}"`)
|
|
22
|
+
return date
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
15
26
|
class SQLiteService extends SQLService {
|
|
16
|
-
init() {
|
|
17
|
-
return super.init(...arguments)
|
|
18
|
-
}
|
|
19
27
|
|
|
20
28
|
get factory() {
|
|
21
29
|
return {
|
|
@@ -23,27 +31,16 @@ class SQLiteService extends SQLService {
|
|
|
23
31
|
create: tenant => {
|
|
24
32
|
const database = this.url4(tenant)
|
|
25
33
|
const dbc = new sqlite(database)
|
|
26
|
-
|
|
27
34
|
const deterministic = { deterministic: true }
|
|
28
35
|
dbc.function('session_context', key => dbc[$session][key])
|
|
29
36
|
dbc.function('regexp', deterministic, (re, x) => (RegExp(re).test(x) ? 1 : 0))
|
|
30
37
|
dbc.function('ISO', deterministic, d => d && new Date(d).toISOString())
|
|
31
|
-
|
|
32
|
-
// define date and time functions in js to allow for throwing errors
|
|
33
|
-
const isTime = /^\d{1,2}:\d{1,2}:\d{1,2}$/
|
|
34
|
-
const hasTimezone = /([+-]\d{1,2}:?\d{0,2}|Z)$/
|
|
35
|
-
const toDate = (d, allowTime = false) => {
|
|
36
|
-
const date = new Date(allowTime && isTime.test(d) ? `1970-01-01T${d}Z` : hasTimezone.test(d) ? d : d + 'Z')
|
|
37
|
-
if (Number.isNaN(date.getTime())) throw new Error(`Value does not contain a valid ${allowTime ? 'time' : 'date'} "${d}"`)
|
|
38
|
-
return date
|
|
39
|
-
}
|
|
40
38
|
dbc.function('year', deterministic, d => d === null ? null : toDate(d).getUTCFullYear())
|
|
41
39
|
dbc.function('month', deterministic, d => d === null ? null : toDate(d).getUTCMonth() + 1)
|
|
42
40
|
dbc.function('day', deterministic, d => d === null ? null : toDate(d).getUTCDate())
|
|
43
41
|
dbc.function('hour', deterministic, d => d === null ? null : toDate(d, true).getUTCHours())
|
|
44
42
|
dbc.function('minute', deterministic, d => d === null ? null : toDate(d, true).getUTCMinutes())
|
|
45
43
|
dbc.function('second', deterministic, d => d === null ? null : toDate(d, true).getUTCSeconds())
|
|
46
|
-
|
|
47
44
|
if (!dbc.memory) dbc.pragma('journal_mode = WAL')
|
|
48
45
|
return dbc
|
|
49
46
|
},
|
|
@@ -118,6 +115,15 @@ class SQLiteService extends SQLService {
|
|
|
118
115
|
yield ']'
|
|
119
116
|
}
|
|
120
117
|
|
|
118
|
+
pragma (pragma, options) {
|
|
119
|
+
if (!this.dbc) return this.begin('pragma') .then (tx => {
|
|
120
|
+
try { return tx.pragma (pragma, options) }
|
|
121
|
+
finally { tx.release() }
|
|
122
|
+
})
|
|
123
|
+
return this.dbc.pragma (pragma, options)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
121
127
|
exec(sql) {
|
|
122
128
|
return this.dbc.exec(sql)
|
|
123
129
|
}
|
|
@@ -242,6 +248,7 @@ class SQLiteService extends SQLService {
|
|
|
242
248
|
Time: () => 'TIME_TEXT',
|
|
243
249
|
DateTime: () => 'DATETIME_TEXT',
|
|
244
250
|
Timestamp: () => 'TIMESTAMP_TEXT',
|
|
251
|
+
Map: () => 'JSON_TEXT'
|
|
245
252
|
}
|
|
246
253
|
|
|
247
254
|
get is_distinct_from_() {
|
|
@@ -262,7 +269,7 @@ class SQLiteService extends SQLService {
|
|
|
262
269
|
try {
|
|
263
270
|
return await super.onINSERT(req)
|
|
264
271
|
} catch (err) {
|
|
265
|
-
throw _not_unique(err, 'ENTITY_ALREADY_EXISTS')
|
|
272
|
+
throw _not_unique(err, 'ENTITY_ALREADY_EXISTS', req.data)
|
|
266
273
|
}
|
|
267
274
|
}
|
|
268
275
|
|
|
@@ -270,7 +277,7 @@ class SQLiteService extends SQLService {
|
|
|
270
277
|
try {
|
|
271
278
|
return await super.onUPDATE(req)
|
|
272
279
|
} catch (err) {
|
|
273
|
-
throw _not_unique(err, 'UNIQUE_CONSTRAINT_VIOLATION')
|
|
280
|
+
throw _not_unique(err, 'UNIQUE_CONSTRAINT_VIOLATION', req.data)
|
|
274
281
|
}
|
|
275
282
|
}
|
|
276
283
|
}
|
|
@@ -283,13 +290,14 @@ class SQLiteService extends SQLService {
|
|
|
283
290
|
// })
|
|
284
291
|
// }
|
|
285
292
|
|
|
286
|
-
function _not_unique(err, code) {
|
|
293
|
+
function _not_unique(err, code, data) {
|
|
287
294
|
if (err.message.match(/unique constraint/i))
|
|
288
295
|
return Object.assign(err, {
|
|
289
296
|
originalMessage: err.message, // FIXME: required because of next line
|
|
290
297
|
message: code, // FIXME: misusing message as code
|
|
291
298
|
code: 400, // FIXME: misusing code as (http) status
|
|
292
299
|
})
|
|
300
|
+
if (data) err.values = SANITIZE_VALUES ? ['***'] : data
|
|
293
301
|
return err
|
|
294
302
|
}
|
|
295
303
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js/sqlite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "CDS database service for SQLite",
|
|
5
5
|
"homepage": "https://github.com/cap-js/cds-dbs/tree/main/sqlite#cds-database-service-for-sqlite",
|
|
6
6
|
"repository": {
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"CHANGELOG.md"
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
|
-
"test": "cds-test
|
|
26
|
+
"test": "cds-test"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@cap-js/db-service": "^1.
|
|
29
|
+
"@cap-js/db-service": "^1.17.0",
|
|
30
30
|
"better-sqlite3": "^11.0.0"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
@@ -37,7 +37,10 @@
|
|
|
37
37
|
"kinds": {
|
|
38
38
|
"sql": {
|
|
39
39
|
"[development]": {
|
|
40
|
-
"kind": "sqlite"
|
|
40
|
+
"kind": "sqlite",
|
|
41
|
+
"credentials": {
|
|
42
|
+
"url": ":memory:"
|
|
43
|
+
}
|
|
41
44
|
}
|
|
42
45
|
},
|
|
43
46
|
"sqlite": {
|