@cap-js/sqlite 1.7.8 → 1.9.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 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.9.0](https://github.com/cap-js/cds-dbs/compare/sqlite-v1.8.0...sqlite-v1.9.0) (2025-03-04)
8
+
9
+
10
+ ### Added
11
+
12
+ * pass through of arbitrary client options ([#1024](https://github.com/cap-js/cds-dbs/issues/1024)) ([b090ccd](https://github.com/cap-js/cds-dbs/commit/b090ccda2dfd4fa535aa0fd5be9d2fc27531db05))
13
+
14
+ ## [1.8.0](https://github.com/cap-js/cds-dbs/compare/sqlite-v1.7.8...sqlite-v1.8.0) (2025-01-28)
15
+
16
+
17
+ ### Added
18
+
19
+ * support for cds.Map ([#889](https://github.com/cap-js/cds-dbs/issues/889)) ([cde7514](https://github.com/cap-js/cds-dbs/commit/cde7514df20396383e0179ffce838596e3706bb2))
20
+
7
21
  ## [1.7.8](https://github.com/cap-js/cds-dbs/compare/sqlite-v1.7.7...sqlite-v1.7.8) (2024-12-16)
8
22
 
9
23
 
@@ -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) => {
@@ -29,7 +30,7 @@ class SQLiteService extends SQLService {
29
30
  options: { max: 1, ...this.options.pool },
30
31
  create: tenant => {
31
32
  const database = this.url4(tenant)
32
- const dbc = new sqlite(database)
33
+ const dbc = new sqlite(database, this.options.client)
33
34
  const deterministic = { deterministic: true }
34
35
  dbc.function('session_context', key => dbc[$session][key])
35
36
  dbc.function('regexp', deterministic, (re, x) => (RegExp(re).test(x) ? 1 : 0))
@@ -247,6 +248,7 @@ class SQLiteService extends SQLService {
247
248
  Time: () => 'TIME_TEXT',
248
249
  DateTime: () => 'DATETIME_TEXT',
249
250
  Timestamp: () => 'TIMESTAMP_TEXT',
251
+ Map: () => 'JSON_TEXT'
250
252
  }
251
253
 
252
254
  get is_distinct_from_() {
@@ -267,7 +269,7 @@ class SQLiteService extends SQLService {
267
269
  try {
268
270
  return await super.onINSERT(req)
269
271
  } catch (err) {
270
- throw _not_unique(err, 'ENTITY_ALREADY_EXISTS')
272
+ throw _not_unique(err, 'ENTITY_ALREADY_EXISTS', req.data)
271
273
  }
272
274
  }
273
275
 
@@ -275,7 +277,7 @@ class SQLiteService extends SQLService {
275
277
  try {
276
278
  return await super.onUPDATE(req)
277
279
  } catch (err) {
278
- throw _not_unique(err, 'UNIQUE_CONSTRAINT_VIOLATION')
280
+ throw _not_unique(err, 'UNIQUE_CONSTRAINT_VIOLATION', req.data)
279
281
  }
280
282
  }
281
283
  }
@@ -288,13 +290,14 @@ class SQLiteService extends SQLService {
288
290
  // })
289
291
  // }
290
292
 
291
- function _not_unique(err, code) {
293
+ function _not_unique(err, code, data) {
292
294
  if (err.message.match(/unique constraint/i))
293
295
  return Object.assign(err, {
294
296
  originalMessage: err.message, // FIXME: required because of next line
295
297
  message: code, // FIXME: misusing message as code
296
298
  code: 400, // FIXME: misusing code as (http) status
297
299
  })
300
+ if (data) err.values = SANITIZE_VALUES ? ['***'] : data
298
301
  return err
299
302
  }
300
303
 
@@ -1,15 +1,158 @@
1
1
  'use strict'
2
2
 
3
3
  const StandardFunctions = {
4
- // Ensure ISO strings are returned for date/time functions
4
+ // ==============================
5
+ // Date and Time Functions
6
+ // ==============================
7
+
8
+ /**
9
+ * Ensures ISO strings are returned for current timestamp
10
+ * @returns {string} - SQL statement
11
+ */
5
12
  current_timestamp: () => 'ISO(current_timestamp)',
6
- // SQLite doesn't support arguments for current_date and current_time
13
+
14
+ /**
15
+ * SQLite doesn't support arguments for current_date
16
+ * @returns {string} - SQL statement
17
+ */
7
18
  current_date: () => 'current_date',
19
+
20
+ /**
21
+ * SQLite doesn't support arguments for current_time
22
+ * @returns {string} - SQL statement
23
+ */
8
24
  current_time: () => 'current_time',
25
+
26
+ /**
27
+ * Generates SQL statement that produces the fractional seconds of a given timestamp
28
+ * @param {string} x - The timestamp input
29
+ * @returns {string} - SQL statement
30
+ */
31
+ fractionalseconds: x => `cast(substr(strftime('%f', ${x}), length(strftime('%f', ${x})) - 3) as REAL)`,
32
+
33
+ // ==============================
34
+ // String Functions
35
+ // ==============================
36
+
37
+ /**
38
+ * Generates SQL statement that produces a boolean value indicating whether the first string contains the second string
39
+ * @param {...string} args - The strings to evaluate
40
+ * @returns {string} - SQL statement
41
+ */
42
+ contains: (...args) => `(ifnull(instr(${args}),0) > 0)`,
43
+
44
+ /**
45
+ * Generates SQL statement that produces the index of the first occurrence of the second string in the first string
46
+ * @param {string} x - The string to search
47
+ * @param {string} y - The substring to find
48
+ * @returns {string} - SQL statement
49
+ */
50
+ indexof: (x, y) => `instr(${x},${y}) - 1`,
51
+
52
+ /**
53
+ * Generates SQL statement that produces a boolean value indicating whether the first string starts with the second string
54
+ * @param {string} x - The string to evaluate
55
+ * @param {string} y - The prefix to check
56
+ * @returns {string} - SQL statement
57
+ */
58
+ startswith: (x, y) => `coalesce(instr(${x},${y}) = 1,false)`,
59
+
60
+ /**
61
+ * Generates SQL statement that produces a boolean value indicating whether the first string ends with the second string
62
+ * @param {string} x - The string to evaluate
63
+ * @param {string} y - The suffix to check
64
+ * @returns {string} - SQL statement
65
+ */
66
+ endswith: (x, y) => `coalesce(substr(${x}, length(${x}) + 1 - length(${y})) = ${y},false)`,
67
+
68
+ /**
69
+ * Generates SQL statement that matches the given string against a regular expression
70
+ * @param {string} x - The string to match
71
+ * @param {string} y - The regular expression
72
+ * @returns {string} - SQL statement
73
+ */
74
+ matchesPattern: (x, y) => `(${x} regexp ${y})`,
75
+
76
+ /**
77
+ * Alias for matchesPattern
78
+ * @param {string} x - The string to match
79
+ * @param {string} y - The regular expression
80
+ * @returns {string} - SQL statement
81
+ */
82
+ matchespattern: (x, y) => `(${x} regexp ${y})`,
9
83
  }
10
84
 
11
85
  const HANAFunctions = {
12
- /** defined in db-service */
86
+ // ==============================
87
+ // Timestamp Difference Functions
88
+ // ==============================
89
+
90
+ /**
91
+ * Generates SQL statement that calculates the difference in 100-nanoseconds between two timestamps
92
+ * @param {string} x - Left timestamp
93
+ * @param {string} y - Right timestamp
94
+ * @returns {string} - SQL statement
95
+ */
96
+ nano100_between: (x, y) => `(julianday(${y}) - julianday(${x})) * 864000000000`,
97
+
98
+ /**
99
+ * Generates SQL statement that calculates the difference in seconds between two timestamps
100
+ * @param {string} x - Left timestamp
101
+ * @param {string} y - Right timestamp
102
+ * @returns {string} - SQL statement
103
+ */
104
+ seconds_between: (x, y) => `(julianday(${y}) - julianday(${x})) * 86400`,
105
+
106
+ /**
107
+ * Generates SQL statement that calculates the difference in days between two timestamps
108
+ * @param {string} x - Left timestamp
109
+ * @param {string} y - Right timestamp
110
+ * @returns {string} - SQL statement
111
+ */
112
+ days_between: (x, y) => `(
113
+ cast(julianday(${y}) as Integer) - cast(julianday(${x}) as Integer)
114
+ ) + (
115
+ case
116
+ when (julianday(${y}) < julianday(${x})) then
117
+ (cast(strftime('%H%M%S%f0000', ${y}) as Integer) < cast(strftime('%H%M%S%f0000', ${x}) as Integer))
118
+ else
119
+ (cast(strftime('%H%M%S%f0000', ${y}) as Integer) > cast(strftime('%H%M%S%f0000', ${x}) as Integer)) * -1
120
+ end
121
+ )`,
122
+
123
+ /**
124
+ * Generates SQL statement that calculates the difference in months between two timestamps
125
+ * @param {string} x - Left timestamp
126
+ * @param {string} y - Right timestamp
127
+ * @returns {string} - SQL statement
128
+ */
129
+ months_between: (x, y) => `
130
+ (
131
+ (
132
+ (cast(strftime('%Y', ${y}) as Integer) - cast(strftime('%Y', ${x}) as Integer)) * 12
133
+ ) + (
134
+ cast(strftime('%m', ${y}) as Integer) - cast(strftime('%m', ${x}) as Integer)
135
+ ) + (
136
+ (
137
+ case
138
+ when (cast(strftime('%Y%m', ${y}) as Integer) < cast(strftime('%Y%m', ${x}) as Integer)) then
139
+ (cast(strftime('%d%H%M%S%f0000', ${y}) as Integer) > cast(strftime('%d%H%M%S%f0000', ${x}) as Integer))
140
+ else
141
+ (cast(strftime('%d%H%M%S%f0000', ${y}) as Integer) < cast(strftime('%d%H%M%S%f0000', ${x}) as Integer)) * -1
142
+ end
143
+ )
144
+ )
145
+ )`,
146
+
147
+ /**
148
+ * Generates SQL statement that calculates the difference in years between two timestamps
149
+ * @param {string} x - Left timestamp
150
+ * @param {string} y - Right timestamp
151
+ * @returns {string} - SQL statement
152
+ */
153
+ years_between(x, y) {
154
+ return `floor(${this.months_between(x, y)} / 12)`
155
+ },
13
156
  }
14
157
 
15
158
  for (let each in HANAFunctions) HANAFunctions[each.toUpperCase()] = HANAFunctions[each]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cap-js/sqlite",
3
- "version": "1.7.8",
3
+ "version": "1.9.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 $(../test/find)"
26
+ "test": "cds-test"
27
27
  },
28
28
  "dependencies": {
29
- "@cap-js/db-service": "^1.14.1",
29
+ "@cap-js/db-service": "^1.18.0",
30
30
  "better-sqlite3": "^11.0.0"
31
31
  },
32
32
  "peerDependencies": {