@cap-js/sqlite 1.4.0 → 1.5.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,23 @@
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.5.0](https://github.com/cap-js/cds-dbs/compare/sqlite-v1.4.0...sqlite-v1.5.0) (2024-02-02)
8
+
9
+
10
+ ### Added
11
+
12
+ * SELECT returns LargeBinaries as streams unless feature flag "stream_compat" is set ([#251](https://github.com/cap-js/cds-dbs/issues/251)) ([8165a4a](https://github.com/cap-js/cds-dbs/commit/8165a4a3f6bb21c970668c8873f9d9c662b43780))
13
+ * Support Readable Streams inside INSERT.entries ([#343](https://github.com/cap-js/cds-dbs/issues/343)) ([f6faf89](https://github.com/cap-js/cds-dbs/commit/f6faf8955b7888479c66f1727ade65b382611c2f))
14
+
15
+
16
+ ### Fixed
17
+
18
+ * config in streaming test with compat flag ([#412](https://github.com/cap-js/cds-dbs/issues/412)) ([335a178](https://github.com/cap-js/cds-dbs/commit/335a1785e216b581759f75154fef7b1b43e6ca17))
19
+ * Do not generate UUIDs for association keys ([#398](https://github.com/cap-js/cds-dbs/issues/398)) ([9970e14](https://github.com/cap-js/cds-dbs/commit/9970e14352679711a9c60807608becff05151fc4))
20
+ * make @cap-js/sqlite work with better-sqlite3@9.3.0 ([#422](https://github.com/cap-js/cds-dbs/issues/422)) ([44c0a59](https://github.com/cap-js/cds-dbs/commit/44c0a59277b14be0b81b7f80555e18377ddbfe3c))
21
+ * sqlite date string compatibility parsing only for valid dates ([#410](https://github.com/cap-js/cds-dbs/issues/410)) ([2a8bb2d](https://github.com/cap-js/cds-dbs/commit/2a8bb2d60940760c6280d8cc06100cb9087194b5)), closes [#409](https://github.com/cap-js/cds-dbs/issues/409)
22
+ * UPSERT for @cap-js/hana for entities with multiple keys ([#418](https://github.com/cap-js/cds-dbs/issues/418)) ([9bbac6e](https://github.com/cap-js/cds-dbs/commit/9bbac6ebbbddfa2f620833ce195eedeb0a79f43e))
23
+
7
24
  ## [1.4.0](https://github.com/cap-js/cds-dbs/compare/sqlite-v1.3.1...sqlite-v1.4.0) (2023-11-20)
8
25
 
9
26
 
@@ -1,11 +1,15 @@
1
1
  const { SQLService } = require('@cap-js/db-service')
2
- const { Readable } = require('stream')
3
2
  const cds = require('@sap/cds/lib')
4
3
  const sqlite = require('better-sqlite3')
5
4
  const $session = Symbol('dbc.session')
6
5
  const convStrm = require('stream/consumers')
6
+ const { Readable } = require('stream')
7
7
 
8
8
  class SQLiteService extends SQLService {
9
+ init() {
10
+ return super.init(...arguments)
11
+ }
12
+
9
13
  get factory() {
10
14
  return {
11
15
  options: { max: 1, ...this.options.pool },
@@ -33,9 +37,6 @@ class SQLiteService extends SQLService {
33
37
  dbc.function('minute', deterministic, d => d === null ? null : toDate(d, true).getUTCMinutes())
34
38
  dbc.function('second', deterministic, d => d === null ? null : toDate(d, true).getUTCSeconds())
35
39
 
36
- dbc.function('json_merge', { varargs: true, deterministic: true }, (...args) =>
37
- args.join('').replace(/}{/g, ','),
38
- )
39
40
  if (!dbc.memory) dbc.pragma('journal_mode = WAL')
40
41
  return dbc
41
42
  },
@@ -80,13 +81,11 @@ class SQLiteService extends SQLService {
80
81
  async _run(stmt, binding_params) {
81
82
  for (let i = 0; i < binding_params.length; i++) {
82
83
  const val = binding_params[i]
84
+ if (val instanceof Readable) {
85
+ binding_params[i] = await convStrm[val.type === 'json' ? 'text' : 'buffer'](val)
86
+ }
83
87
  if (Buffer.isBuffer(val)) {
84
- binding_params[i] = Buffer.from(val.base64Slice())
85
- } else if (typeof val === 'object' && val && val.pipe) {
86
- // REVISIT: stream.setEncoding('base64') sometimes misses the last bytes
87
- // if (val.type === 'binary') val.setEncoding('base64')
88
- binding_params[i] = await convStrm.buffer(val)
89
- if (val.type === 'binary') binding_params[i] = Buffer.from(binding_params[i].toString('base64'))
88
+ binding_params[i] = Buffer.from(val.toString('base64'))
90
89
  }
91
90
  }
92
91
  return stmt.run(binding_params)
@@ -112,36 +111,25 @@ class SQLiteService extends SQLService {
112
111
  yield ']'
113
112
  }
114
113
 
115
- async _stream(stmt, binding_params, one) {
116
- const columns = stmt.columns()
117
- // Stream single blob column
118
- if (columns.length === 1 && columns[0].name !== '_json_') {
119
- // Setting result set to raw to keep better-sqlite from doing additional processing
120
- stmt.raw(true)
121
- const rows = stmt.all(binding_params)
122
- // REVISIT: return undefined when no rows are found
123
- if (rows.length === 0) return undefined
124
- if (rows[0][0] === null) return null
125
- // Buffer.from only applies encoding when the input is a string
126
- let raw = Buffer.from(rows[0][0].toString(), 'base64')
127
- stmt.raw(false)
128
- return new Readable({
129
- read(size) {
130
- if (raw.length === 0) return this.push(null)
131
- const chunk = raw.slice(0, size)
132
- raw = raw.slice(size)
133
- this.push(chunk)
134
- },
135
- })
136
- }
114
+ exec(sql) {
115
+ return this.dbc.exec(sql)
116
+ }
137
117
 
138
- stmt.raw(true)
139
- const rs = stmt.iterate(binding_params)
140
- return Readable.from(this._iterator(rs, one))
118
+ _prepareStreams(values) {
119
+ let any
120
+ values.forEach((v, i) => {
121
+ if (v instanceof Readable) {
122
+ any = values[i] = convStrm.buffer(v)
123
+ }
124
+ })
125
+ return any ? Promise.all(values) : values
141
126
  }
142
127
 
143
- exec(sql) {
144
- return this.dbc.exec(sql)
128
+ async onSIMPLE({ query, data }) {
129
+ const { sql, values } = this.cqn2sql(query, data)
130
+ let ps = await this.prepare(sql)
131
+ const vals = await this._prepareStreams(values)
132
+ return (await ps.run(vals)).changes
145
133
  }
146
134
 
147
135
  onPlainSQL({ query, data }, next) {
@@ -172,8 +160,14 @@ class SQLiteService extends SQLService {
172
160
  }
173
161
 
174
162
  val(v) {
163
+ if (Buffer.isBuffer(v.val)) v.val = v.val.toString('base64')
175
164
  // intercept DateTime values and convert to Date objects to compare ISO Strings
176
- if (/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[Z+-]/.test(v.val)) v.val = new Date(v.val)
165
+ else if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(.\d{1,9})?(Z|[+-]\d{2}(:?\d{2})?)$/.test(v.val)) {
166
+ const date = new Date(v.val)
167
+ if (!Number.isNaN(date.getTime())) {
168
+ v.val = date
169
+ }
170
+ }
177
171
  return super.val(v)
178
172
  }
179
173
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cap-js/sqlite",
3
- "version": "1.4.0",
3
+ "version": "1.5.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": {
@@ -30,11 +30,11 @@
30
30
  "test": "jest --silent"
31
31
  },
32
32
  "dependencies": {
33
- "@cap-js/db-service": "^1.3.1",
34
- "better-sqlite3": "^9"
33
+ "@cap-js/db-service": "^1.6.0",
34
+ "better-sqlite3": "^9.3.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "@sap/cds": ">=7"
37
+ "@sap/cds": ">=7.6"
38
38
  },
39
39
  "cds": {
40
40
  "requires": {