@mlagie/sql-connector 1.2.3 → 1.3.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/README.md +24 -0
- package/package.json +1 -1
- package/src/models/Model.js +48 -1
package/README.md
CHANGED
|
@@ -149,6 +149,30 @@ const transferSchema = new Schema({
|
|
|
149
149
|
2. **De supprimer le backup** après restauration ou non.
|
|
150
150
|
3. Si vous refusez la suppression, le backup est renommé en `.ignored` et ne sera plus proposé.
|
|
151
151
|
|
|
152
|
+
### Synchronisation intelligente des colonnes
|
|
153
|
+
|
|
154
|
+
Lors de la synchronisation (`Model.syncAllTables()`), le module compare chaque colonne existante avec la définition du schéma JS :
|
|
155
|
+
|
|
156
|
+
- **Type** : Si le type SQL attendu diffère de celui en base, la colonne est modifiée.
|
|
157
|
+
- **Nullabilité** : Si la contrainte `NOT NULL` ou `NULL` diffère, la colonne est modifiée.
|
|
158
|
+
> ⚠️ Une colonne `primary_key` est toujours considérée comme `NOT NULL` même si `required` n'est pas précisé.
|
|
159
|
+
- **Valeur par défaut** : Si la valeur par défaut diffère, la colonne est modifiée.
|
|
160
|
+
- **Unique** : Si la contrainte `UNIQUE` diffère, la colonne est modifiée.
|
|
161
|
+
- **Primary key** : Si la contrainte `PRIMARY KEY` diffère, la colonne est modifiée.
|
|
162
|
+
|
|
163
|
+
Seules les différences réelles entraînent une modification SQL, ce qui évite les migrations inutiles.
|
|
164
|
+
|
|
165
|
+
> **Note :**
|
|
166
|
+
> Il est interdit de déclarer une colonne à la fois `primary_key: true` et `unique: true` dans le schéma JS.
|
|
167
|
+
> **Explication :** En SQL, une clé primaire (`PRIMARY KEY`) est déjà unique par définition et impose la contrainte `UNIQUE` et `NOT NULL` sur la colonne. Ajouter explicitement `unique: true` en plus de `primary_key: true` est redondant et provoque une erreur SQL ("Multiple primary key defined").
|
|
168
|
+
>
|
|
169
|
+
> **En résumé :**
|
|
170
|
+
> - Utilisez seulement `primary_key: true` pour une colonne qui doit être la clé primaire.
|
|
171
|
+
> - Utilisez `unique: true` pour une colonne qui doit être unique mais n'est pas la clé primaire.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
|
|
152
176
|
#### Exemple d’utilisation
|
|
153
177
|
|
|
154
178
|
```js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mlagie/sql-connector",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Le module sql-connector permet de gérer les connexions à une base de données MySQL, de définir des schémas de tables, et d'interagir avec les données de manière simple et efficace.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
package/src/models/Model.js
CHANGED
|
@@ -6,6 +6,7 @@ const formatObject = require("../utils/formatObject");
|
|
|
6
6
|
const fs = require('fs');
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const glob = require('glob');
|
|
9
|
+
const { ModelInstance } = require("./ModelInstance");
|
|
9
10
|
|
|
10
11
|
function getFieldType(field) {
|
|
11
12
|
if (typeof field === "object") {
|
|
@@ -51,6 +52,10 @@ function ifReservedKeywords(tableName) {
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
function getColumnDefinition(fieldName, field) {
|
|
55
|
+
if (field.primary_key && field.unique) {
|
|
56
|
+
throw new Error(`Field '${fieldName}' cannot be both PRIMARY KEY and UNIQUE.`);
|
|
57
|
+
}
|
|
58
|
+
|
|
54
59
|
const fieldType = getFieldType(field);
|
|
55
60
|
let colDef = "";
|
|
56
61
|
|
|
@@ -232,8 +237,50 @@ class Model {
|
|
|
232
237
|
);
|
|
233
238
|
let existingCols = columns.map(col => col.Field);
|
|
234
239
|
|
|
235
|
-
// --- Warn si oldName est présent dans le schéma ---
|
|
236
240
|
for (const [fieldName, field] of Object.entries(model.schema.schemaDict)) {
|
|
241
|
+
if (existingCols.includes(fieldName)) {
|
|
242
|
+
// 1. Récupère infos colonne
|
|
243
|
+
const currentCol = columns.find(col => col.Field === fieldName);
|
|
244
|
+
const [indexes] = await conn.promise().query(
|
|
245
|
+
`SHOW INDEX FROM \`${model.name}\` WHERE Column_name = ?`, [fieldName]
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
// 2. Vérifie les propriétés principales
|
|
249
|
+
let needModify = false;
|
|
250
|
+
|
|
251
|
+
// Type
|
|
252
|
+
const expectedType = sqlTypeMap[getFieldType(field)]?.toUpperCase();
|
|
253
|
+
const dbType = currentCol.Type.toUpperCase().split('(')[0];
|
|
254
|
+
if (expectedType !== dbType)
|
|
255
|
+
needModify = true;
|
|
256
|
+
|
|
257
|
+
// Nullability check
|
|
258
|
+
const shouldBeNotNull = field.required === true || field.primary_key === true;
|
|
259
|
+
if ((shouldBeNotNull && currentCol.Null === "YES") || (!shouldBeNotNull && currentCol.Null === "NO"))
|
|
260
|
+
needModify = true;
|
|
261
|
+
|
|
262
|
+
// Default
|
|
263
|
+
if ((field.default ?? null) != (currentCol.Default ?? null))
|
|
264
|
+
needModify = true;
|
|
265
|
+
|
|
266
|
+
// Unique
|
|
267
|
+
const isUniqueInDB = indexes.some(idx => idx.Non_unique === 0 && idx.Key_name !== 'PRIMARY');
|
|
268
|
+
if (!!field.unique !== isUniqueInDB)
|
|
269
|
+
needModify = true;
|
|
270
|
+
|
|
271
|
+
// Primary key
|
|
272
|
+
const isPrimaryInDB = indexes.some(idx => idx.Key_name === 'PRIMARY');
|
|
273
|
+
if (!!field.primary_key !== isPrimaryInDB)
|
|
274
|
+
needModify = true;
|
|
275
|
+
|
|
276
|
+
// 3. Si différence, on modifie
|
|
277
|
+
if (needModify) {
|
|
278
|
+
const newColDef = getColumnDefinition(fieldName, field);
|
|
279
|
+
const alterSQL = `ALTER TABLE \`${model.name}\` MODIFY COLUMN ${newColDef}`;
|
|
280
|
+
await conn.promise().query(alterSQL);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// --- Warn si oldName est présent dans le schéma ---
|
|
237
284
|
if (field.oldName) {
|
|
238
285
|
logs(`⚠️ Pensez à retirer la propriété 'oldName' du champ '${fieldName}' dans le schéma JS de '${model.name}' pour éviter des renommages inutiles à l'avenir.`);
|
|
239
286
|
}
|