@balena/pinejs 20.0.1-build-rollbackable-migrations-guide-3ca5787deb64488fb03a0a6aa1a22633f4a61bec-2 → 20.0.1-build-compile-in-as-eq-any-ea01cb61393cdd9adfe8bea633235cfd81435554-1
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.
@@ -1,15 +1,15 @@
|
|
1
1
|
- commits:
|
2
|
-
- subject:
|
3
|
-
hash:
|
2
|
+
- subject: Compile in as (= ANY($singleListBinding))
|
3
|
+
hash: ea01cb61393cdd9adfe8bea633235cfd81435554
|
4
4
|
body: ""
|
5
5
|
footer:
|
6
6
|
Change-type: patch
|
7
7
|
change-type: patch
|
8
|
-
author:
|
8
|
+
author: Otavio Jacobi
|
9
9
|
nested: []
|
10
10
|
version: 20.0.1
|
11
11
|
title: ""
|
12
|
-
date: 2025-01-
|
12
|
+
date: 2025-01-20T17:39:13.474Z
|
13
13
|
- commits:
|
14
14
|
- subject: Update node engines entry to clarify we don't actively support 21.x
|
15
15
|
hash: bb75825da9bf23f38f1c0fe2bae301d171d84de6
|
package/CHANGELOG.md
CHANGED
@@ -5,9 +5,9 @@ automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
|
|
5
5
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
6
6
|
|
7
7
|
# v20.0.1
|
8
|
-
## (2025-01-
|
8
|
+
## (2025-01-20)
|
9
9
|
|
10
|
-
*
|
10
|
+
* Compile in as (= ANY($singleListBinding)) [Otavio Jacobi]
|
11
11
|
|
12
12
|
# v20.0.0
|
13
13
|
## (2025-01-10)
|
package/docs/Migrations.md
CHANGED
@@ -65,6 +65,23 @@ Async migrations are stored in the migrations folder, alongside synchronous migr
|
|
65
65
|
The async migration query must have a `LIMIT` statement to limit the maximum number of affected rows per batch.
|
66
66
|
|
67
67
|
|
68
|
+
### Async migration procedure
|
69
|
+
* Deployment 1
|
70
|
+
- Add new column (with independent sync migration) to contain new data and add code accessing the new column.
|
71
|
+
- Update the service's implementation to set both the old & new column on each write.
|
72
|
+
- The service's implementation should only read the old column since the async migration still migrates data from old column to new column.
|
73
|
+
- Async migrator runs forever.
|
74
|
+
* Deployment 2
|
75
|
+
- Finalize async migration => only sync migration part gets executed.
|
76
|
+
- Sync migration migrates all left over data from old column to new column.
|
77
|
+
- Update the service's implementation to only read the new column, but still write the old one as well.
|
78
|
+
- Mark the old field as optional in the sbvr if it isn't, or set a default value for it.
|
79
|
+
* Deployment 3
|
80
|
+
- Update the service's implementation to stop settings the old column and remove it from the sbvr.
|
81
|
+
- Make the old field NULLable if it isn't.
|
82
|
+
* Deployment 4
|
83
|
+
- Delete the old column with a sync migration.
|
84
|
+
|
68
85
|
### TS migration file format with SQL query string
|
69
86
|
|
70
87
|
The placeholder `%%ASYNC_BATCH_SIZE%%` will be replaced with the value specified by asyncBatchSize parameter
|
@@ -130,34 +147,4 @@ export = {
|
|
130
147
|
|
131
148
|
```
|
132
149
|
### SQL query file (plain text)
|
133
|
-
Plain SQL files are not supported as they cannot bundle async and sync migration statements in one file. Moreover they cannot carry migration metadata.
|
134
|
-
|
135
|
-
## Rollbackable no-down-time suggested migration procedure
|
136
|
-
|
137
|
-
* Deployment 1
|
138
|
-
- Add the new column with an independent sync migration.
|
139
|
-
- Add an Async migrator that starts migrating data from the old column to new column (optional optimization for big tables).
|
140
|
-
- Update the service's implementation to set both the old & new column on each write.
|
141
|
-
The service's implementation should only read the old column, since not all data has been migrated to the new column yet.
|
142
|
-
* Deployment 2
|
143
|
-
- Complete the data migration from the old to the new column:
|
144
|
-
- Either finalize the async migration from deployment 1 if you are using one.
|
145
|
-
This causes the sync part of the migration to execute.
|
146
|
-
- Or write a sync migration otherwise.
|
147
|
-
- Mark the new column as non-NULL if applicable as part of the above migration.
|
148
|
-
- Update the service's implementation to only read the new column, but still write to the old one as well.
|
149
|
-
- Test that the implementation works even if we keep the old column as NOT NULLable.
|
150
|
-
This makes sure that older service instances can still work during the deployment.
|
151
|
-
- Mark the old field as NULLable if it isn't.
|
152
|
-
* Deployment 3
|
153
|
-
- Update the service's implementation to stop writing to the old column
|
154
|
-
- Remove the old column from the SBVR, leaving a TODO to also DROP if from the DB in a follow-up.
|
155
|
-
The old column needs to stay in the DB so that older service instances can still work during the deployment.
|
156
|
-
* Deployment 4
|
157
|
-
- DROP the old column with a sync migration.
|
158
|
-
|
159
|
-
### Testing rollbacks
|
160
|
-
For each step, be sure and utilize testing to ensure you can safely rollback to previous versions of your service even with the updated database schemas (with data) deployed.
|
161
|
-
Before merging each step, try rolling back your development environment to the previous deployment and make sure that everything still works without issues.
|
162
|
-
The old deployment should be able to operate with DB records created by the new deployment and leave the DB in a valid state.
|
163
|
-
Eg: While testing the PR for deployment 2 on your development environment, make sure that if you push deplpoyment 1 everything still works without issues.
|
150
|
+
Plain SQL files are not supported as they cannot bundle async and sync migration statements in one file. Moreover they cannot carry migration metadata.
|
@@ -99,13 +99,24 @@ export const getAndCheckBindValues = async (request, bindings) => {
|
|
99
99
|
throw new Error(`Bind value cannot be undefined: ${binding}`);
|
100
100
|
}
|
101
101
|
try {
|
102
|
-
return await
|
102
|
+
return await validateBindingType(engine, value, field);
|
103
103
|
}
|
104
104
|
catch (err) {
|
105
105
|
throw new BadRequestError(`"${fieldName}" ${err.message}`);
|
106
106
|
}
|
107
107
|
}));
|
108
108
|
};
|
109
|
+
const validateBindingType = async (engine, $value, field) => {
|
110
|
+
if (field.dataType === 'List') {
|
111
|
+
if (!Array.isArray($value)) {
|
112
|
+
throw new Error('List value binding must be an array');
|
113
|
+
}
|
114
|
+
return await Promise.all($value.map(async ([dataType, value]) => {
|
115
|
+
return await validateBindingType(engine, value, { dataType });
|
116
|
+
}));
|
117
|
+
}
|
118
|
+
return await AbstractSQLCompiler[engine].dataTypeValidate($value, field);
|
119
|
+
};
|
109
120
|
const checkModifiedFields = (ruleReferencedFields, modifiedFields) => {
|
110
121
|
const refs = ruleReferencedFields[modifiedFields.table];
|
111
122
|
if (refs == null) {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"abstract-sql.js","sourceRoot":"","sources":["../../src/sbvr-api/abstract-sql.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAC;
|
1
|
+
{"version":3,"file":"abstract-sql.js","sourceRoot":"","sources":["../../src/sbvr-api/abstract-sql.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@balena/pinejs",
|
3
|
-
"version": "20.0.1-build-
|
3
|
+
"version": "20.0.1-build-compile-in-as-eq-any-ea01cb61393cdd9adfe8bea633235cfd81435554-1",
|
4
4
|
"main": "out/server-glue/module.js",
|
5
5
|
"type": "module",
|
6
6
|
"repository": "git@github.com:balena-io/pinejs.git",
|
@@ -26,12 +26,12 @@
|
|
26
26
|
"generate-types": "node ./bin/sbvr-compiler.js generate-types ./src/sbvr-api/user.sbvr ./src/sbvr-api/user.ts && node ./bin/sbvr-compiler.js generate-types ./src/migrator/migrations.sbvr ./src/migrator/migrations.ts && node ./bin/sbvr-compiler.js generate-types ./src/sbvr-api/dev.sbvr ./src/sbvr-api/dev.ts && node ./bin/sbvr-compiler.js generate-types ./src/tasks/tasks.sbvr ./src/tasks/tasks.ts && balena-lint -t tsconfig.dev.json --fix ./src/sbvr-api/user.ts ./src/migrator/migrations.ts ./src/sbvr-api/dev.ts"
|
27
27
|
},
|
28
28
|
"dependencies": {
|
29
|
-
"@balena/abstract-sql-compiler": "
|
29
|
+
"@balena/abstract-sql-compiler": "10.2.0-build-compile-any-node-as-operand-77c25f0bfe74e1d1b8c5c46dddb5c14658c7144c-1",
|
30
30
|
"@balena/abstract-sql-to-typescript": "^5.1.0",
|
31
31
|
"@balena/env-parsing": "^1.2.0",
|
32
32
|
"@balena/lf-to-abstract-sql": "^5.0.3",
|
33
|
-
"@balena/odata-parser": "
|
34
|
-
"@balena/odata-to-abstract-sql": "
|
33
|
+
"@balena/odata-parser": "4.0.0-build-compile-in-as-eq-any-920795378e7f3a4c819d178be879570f48ebc3cb-1",
|
34
|
+
"@balena/odata-to-abstract-sql": "7.1.0-build-parse-in-as-eq-any-ede1d0fa541f53ca2ae55cd443490ac2cd0e1c11-1",
|
35
35
|
"@balena/sbvr-parser": "^1.4.6",
|
36
36
|
"@balena/sbvr-types": "^9.1.0",
|
37
37
|
"@types/body-parser": "^1.19.5",
|
@@ -148,6 +148,6 @@
|
|
148
148
|
"recursive": true
|
149
149
|
},
|
150
150
|
"versionist": {
|
151
|
-
"publishedAt": "2025-01-
|
151
|
+
"publishedAt": "2025-01-20T17:39:14.502Z"
|
152
152
|
}
|
153
153
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import _ from 'lodash';
|
2
2
|
|
3
|
+
import type { Engines } from '@balena/abstract-sql-compiler';
|
3
4
|
import AbstractSQLCompiler from '@balena/abstract-sql-compiler';
|
4
5
|
import type { BindKey } from '@balena/odata-parser';
|
5
6
|
import {
|
@@ -140,7 +141,7 @@ export const getAndCheckBindValues = async (
|
|
140
141
|
}
|
141
142
|
|
142
143
|
try {
|
143
|
-
return await
|
144
|
+
return await validateBindingType(engine, value, field);
|
144
145
|
} catch (err: any) {
|
145
146
|
throw new BadRequestError(`"${fieldName}" ${err.message}`);
|
146
147
|
}
|
@@ -148,6 +149,24 @@ export const getAndCheckBindValues = async (
|
|
148
149
|
);
|
149
150
|
};
|
150
151
|
|
152
|
+
const validateBindingType = async (
|
153
|
+
engine: Engines,
|
154
|
+
$value: any,
|
155
|
+
field: { dataType: string },
|
156
|
+
): Promise<any> => {
|
157
|
+
if (field.dataType === 'List') {
|
158
|
+
if (!Array.isArray($value)) {
|
159
|
+
throw new Error('List value binding must be an array');
|
160
|
+
}
|
161
|
+
return await Promise.all(
|
162
|
+
$value.map(async ([dataType, value]: [string, any]) => {
|
163
|
+
return await validateBindingType(engine, value, { dataType });
|
164
|
+
}),
|
165
|
+
);
|
166
|
+
}
|
167
|
+
return await AbstractSQLCompiler[engine].dataTypeValidate($value, field);
|
168
|
+
};
|
169
|
+
|
151
170
|
const checkModifiedFields = (
|
152
171
|
ruleReferencedFields: AbstractSQLCompiler.RuleReferencedFields,
|
153
172
|
modifiedFields: AbstractSQLCompiler.ModifiedFields,
|