58 lines
2.4 KiB
Python
58 lines
2.4 KiB
Python
from ..connection import connect
|
|
from ..constants import FIELD_TYPES
|
|
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):
|
|
"""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)."""
|
|
ensure_field_bounds_schema(slug)
|
|
conn = connect(slug)
|
|
tname = table_name_for(name)
|
|
|
|
conn.execute(
|
|
"INSERT INTO _definitions (name, table_name) VALUES (?, ?)", (name, tname)
|
|
)
|
|
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"{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"{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("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
|