@mlagie/sql-connector 3.3.0 → 3.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mlagie/sql-connector",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "description": "The sql-connector module allows you to manage connections to a MySQL database, define table schemas, and interact with data in a simple and efficient way.",
5
5
  "main": "index.js",
6
6
  "exports": {
@@ -61,6 +61,11 @@ class MigrationRunner {
61
61
  plan.id
62
62
  );
63
63
 
64
+ // The rollback files are written BEFORE the schema is touched: if the
65
+ // process dies or the write fails, nothing has been changed yet and the
66
+ // database never ends up "applied" without its rollback metadata.
67
+ await this.store.writeMigration(plan);
68
+
64
69
  const run = async () => {
65
70
  for (const operation of plan.operations) {
66
71
  const sql = this.sqlForOperation(operation);
@@ -75,15 +80,31 @@ class MigrationRunner {
75
80
  );
76
81
  };
77
82
 
78
- await this.dialect.transaction(this.connection, run);
79
- await this.store.writeMigration(plan);
80
- await this.store.writeSnapshot(plan.snapshot);
81
- await this.store.cleanup();
83
+ try {
84
+ await this.dialect.transaction(this.connection, run);
85
+ } catch (error) {
86
+ await this.store.removeMigration(plan.id).catch(() => {});
87
+ throw error;
88
+ }
89
+
90
+ const warnings = [];
91
+ try {
92
+ await this.store.writeSnapshot(plan.snapshot);
93
+ } catch (error) {
94
+ warnings.push(`Migration applied but schema snapshot could not be written: ${error.message}`);
95
+ }
96
+ try {
97
+ await this.store.cleanup();
98
+ } catch (error) {
99
+ warnings.push(`Migration applied but cleanup failed: ${error.message}`);
100
+ }
101
+ for (const warning of warnings) console.warn(warning);
82
102
 
83
103
  return {
84
104
  applied: true,
85
105
  plan,
86
- backupPath
106
+ backupPath,
107
+ ...(warnings.length > 0 ? { warnings } : {})
87
108
  };
88
109
  }
89
110
 
@@ -43,6 +43,11 @@ class MigrationStore {
43
43
  return outputPath;
44
44
  }
45
45
 
46
+ async removeMigration(id) {
47
+ await fs.rm(path.join(this.directory, `${id}.sql.enc`), { force: true });
48
+ await fs.rm(path.join(this.directory, `${id}.meta.json.enc`), { force: true });
49
+ }
50
+
46
51
  async readMigration(id) {
47
52
  await this.ensureDirectories();
48
53
  if (!this.encryptionKey) throw new Error("An encryption key is required to read migration files.");
@@ -134,4 +139,4 @@ class MigrationStore {
134
139
  }
135
140
  }
136
141
 
137
- module.exports = { MigrationStore };
142
+ module.exports = { MigrationStore };