from ..connection import connect from ..constants import FIELD_TYPES from ..quote_ident import quote_ident from ..slugify import slugify from ..table_name_for import table_name_for from .get_definition import get_definition from .ensure_field_bounds_schema import ensure_field_bounds_schema def create_definition(slug, name, fields, per_player=True): """Feature 2 : crée une définition d'objet (comme une table de BDD) et exécute le vrai CREATE TABLE correspondant, avec les bons types de colonne, y compris les colonnes de clé étrangère pour les relations vers d'autres définitions déjà créées dans CE jeu (une définition peut donc "en contenir" une autre, au sens relationnel). per_player (état par joueur, Phase 1) : True (par défaut) = chaque joueur a ses propres lignes (une table player_id-scopée qui démarre VIDE pour chaque nouveau joueur — pas de valeur par défaut à copier, contrairement à une variable globale, voir db/global_vars/update_global_variable_value.py) ; False = lignes partagées par tous les joueurs (ex. un catalogue/une liste de questions), toujours player_id=PLAYER_SHARED quel que soit le joueur qui consulte.""" ensure_field_bounds_schema(slug) conn = connect(slug) tname = table_name_for(name) conn.execute( "INSERT INTO _definitions (name, table_name, per_player) VALUES (?, ?, ?)", (name, tname, 1 if per_player else 0), ) definition_id = conn.execute("SELECT last_insert_rowid() AS id").fetchone()["id"] columns_sql = ["id INTEGER PRIMARY KEY AUTOINCREMENT"] for pos, f in enumerate(fields): fname = slugify(f["name"]).replace("-", "_") ftype = f["type"] required = 1 if f.get("required") else 0 relation_definition_id = None if ftype == "relation": related = get_definition(slug, int(f["relation_definition_id"])) col = f"{fname}_id" columns_sql.append( f"{quote_ident(col)} INTEGER REFERENCES {related['table_name']}(id)" ) relation_definition_id = related["id"] else: sql_type = FIELD_TYPES[ftype]["sql"] not_null = " NOT NULL" if required else "" columns_sql.append(f"{quote_ident(fname)} {sql_type}{not_null}") min_value = f.get("min_value") if ftype in ("nombre_entier", "nombre_decimal") else None max_value = f.get("max_value") if ftype in ("nombre_entier", "nombre_decimal") else None conn.execute( """INSERT INTO _fields (definition_id, name, type, relation_definition_id, required, position, min_value, max_value) VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", (definition_id, f["name"], ftype, relation_definition_id, required, pos, min_value, max_value), ) columns_sql.append("player_id TEXT NOT NULL DEFAULT '__shared__'") columns_sql.append("created_at TEXT DEFAULT CURRENT_TIMESTAMP") create_sql = f"CREATE TABLE {tname} ({', '.join(columns_sql)})" conn.execute(create_sql) conn.commit() conn.close() return definition_id