import sqlite3 from ..connection import connect from ..slugify import slugify from .get_definition import get_definition def update_field(slug, definition_id, field_id, new_name, required, relation_definition_id=None, min_value=None, max_value=None): """CRUD — Update d'une définition : modifie un champ déjà créé (nom, obligatoire, objet lié si c'est une relation, et bornes mini/maxi si c'est un champ numérique — voir 2.2, bornage automatique). Si le nom change, la vraie colonne SQL est renommée (ALTER TABLE ... RENAME COLUMN, SQLite ≥ 3.25) pour que la colonne réelle continue de correspondre exactement au nom du champ tel qu'affiché — pas de dérive entre la définition et la table. Le TYPE d'un champ existant ne se change pas ici (une vraie conversion de type SQLite demanderait de reconstruire la table et de convertir les données déjà enregistrées, hors scope de cette version).""" definition = get_definition(slug, definition_id) field = next((f for f in definition["fields"] if f["id"] == field_id), None) if not field: return old_col = slugify(field["name"]).replace("-", "_") new_col = slugify(new_name).replace("-", "_") if field["type"] == "relation": old_col += "_id" new_col += "_id" conn = connect(slug) if old_col != new_col: try: conn.execute( f"ALTER TABLE {definition['table_name']} RENAME COLUMN {old_col} TO {new_col}" ) except sqlite3.OperationalError: pass # SQLite trop ancien pour RENAME COLUMN : la colonne SQL garde son ancien nom rel_id = int(relation_definition_id) if (field["type"] == "relation" and relation_definition_id) else field["relation_definition_id"] is_numeric = field["type"] in ("nombre_entier", "nombre_decimal") min_v = (min_value if min_value not in (None, "") else None) if is_numeric else None max_v = (max_value if max_value not in (None, "") else None) if is_numeric else None conn.execute( "UPDATE _fields SET name = ?, required = ?, relation_definition_id = ?, min_value = ?, max_value = ? WHERE id = ?", (new_name, 1 if required else 0, rel_id, min_v, max_v, field_id), ) conn.commit() conn.close()