-
Notifications
You must be signed in to change notification settings - Fork 17
Base_de_données
Archéo Lex importe les codes de la base LEGI dans un base de données SQLite. Cette base de données SQLite permet d’avoir de pouvoir requêter facilement afin de créer les textes de loi dans les formats demandés, ainsi que de pouvoir recréer des textes déjà compilés (reproductible data), sous réserve d’avoir encore les textes des articles dans leur version d’alors puisqu’ils ne sont pas enregistrés pour des questions de place.
(ce paragraphe a été écrit avant la v2.0 et n’est plus à jour)
La base de données comprend deux types d’informations :
- la base LEGI en tant que donnée brute importée : tables
texte
,section
,article
avec diverses métadonnées ; - les versions consolidées des codes tels que calculés par le programme, puisque cette information n’est pas donnée explicitement dans la base LEGI (il faut rassembler toutes les dates de consolidation mentionnées pour obtenir l’ensemble des versions consolidées) : tables
version_texte
,version_section
.
De plus, pour permettre de modifier de façon incrémentale les dépôts Git en sortie au fur et à mesure de la mise à jour de la base LEGI, chaque enregistrement dans la base de données est également étiqueté avec la date de la dernière mise à jour du code dans la base LEGI [il faut ajouter ces tags dans la BDD]. Ainsi, lorsqu’une section est mise à jour dans la base LEGI, un enregistrement dans version_section
est créé ainsi qu’un nouveau lien entre article
et version_section
[il faut ajouter une table version_section_article ou version_article]. De même, lorsqu’un article est mis à jour dans la base LEGI, un enregistrement dans article
[ou version_article] ainsi qu’un lien [même remarque que précédemment].
texte
CREATE TABLE "texte" (
"cid" VARCHAR(20) NOT NULL PRIMARY KEY,
"nor" VARCHAR(20) NOT NULL,
"nature" VARCHAR(20) NOT NULL,
"date_texte" DATE,
"date_publi" DATE
);
version_texte
CREATE TABLE "version_texte" (
"id" INTEGER NOT NULL PRIMARY KEY,
"texte_id" VARCHAR(20) NOT NULL,
"titre" VARCHAR(200) NOT NULL,
"titre_long" VARCHAR(200) NOT NULL,
"etat_juridique" VARCHAR(25) NOT NULL,
"debut" DATE,
"fin" DATE,
"base_id" INTEGER,
FOREIGN KEY ("texte_id") REFERENCES "texte" ("cid"),
FOREIGN KEY ("base_id") REFERENCES "version_texte" ("id")
);
CREATE INDEX "version_texte_base_id" ON "version_texte" ("base_id");
CREATE INDEX "version_texte_texte_id" ON "version_texte" ("texte_id");
section
CREATE TABLE "section" (
"cid" VARCHAR(20) NOT NULL PRIMARY KEY,
"cid_parent_id" VARCHAR(20),
"niveau" INTEGER NOT NULL,
"texte_id" VARCHAR(20) NOT NULL,
FOREIGN KEY ("cid_parent_id") REFERENCES "section" ("cid"),
FOREIGN KEY ("texte_id") REFERENCES "texte" ("cid")
);
CREATE INDEX "section_cid_parent_id" ON "section" ("cid_parent_id");
CREATE INDEX "section_texte_id" ON "section" ("texte_id");
version_section
CREATE TABLE "version_section" (
"id" VARCHAR(20) NOT NULL PRIMARY KEY,
"cid_id" VARCHAR(20) NOT NULL,
"id_parent_id" VARCHAR(20),
"nom" VARCHAR(200) NOT NULL,
"etat_juridique" VARCHAR(25) NOT NULL,
"niveau" INTEGER NOT NULL,
"numero" INTEGER NOT NULL,
"debut" DATE NOT NULL,
"fin" DATE, "texte_id" VARCHAR(20) NOT NULL,
"version_texte_id" INTEGER,
FOREIGN KEY ("cid_id") REFERENCES "section" ("cid"),
FOREIGN KEY ("id_parent_id") REFERENCES "version_section" ("id"),
FOREIGN KEY ("texte_id") REFERENCES "texte" ("cid"),
FOREIGN KEY ("version_texte_id") REFERENCES "version_texte" ("id")
);
CREATE INDEX "version_section_cid_id" ON "version_section" ("cid_id");
CREATE INDEX "version_section_id_parent_id" ON "version_section" ("id_parent_id");
CREATE INDEX "version_section_texte_id" ON "version_section" ("texte_id");
CREATE INDEX "version_section_version_texte_id" ON "version_section" ("version_texte_id");
article
CREATE TABLE "article" (
"id" VARCHAR(20) NOT NULL PRIMARY KEY,
"nom" VARCHAR(200) NOT NULL,
"etat_juridique" VARCHAR(25) NOT NULL,
"num" VARCHAR(200) NOT NULL,
"debut" DATE NOT NULL,
"fin" DATE,
"texte_id" VARCHAR(20) NOT NULL,
"version_section_id" VARCHAR(20) NOT NULL,
"version_texte_id" INTEGER NOT NULL,
FOREIGN KEY ("texte_id") REFERENCES "texte" ("cid"),
FOREIGN KEY ("version_section_id") REFERENCES "version_section" ("id"),
FOREIGN KEY ("version_texte_id") REFERENCES "version_texte" ("id")
);
CREATE INDEX "article_texte_id" ON "article" ("texte_id");
CREATE INDEX "article_version_section_id" ON "article" ("version_section_id");
CREATE INDEX "article_version_texte_id" ON "article" ("version_texte_id");
Cette version apporte principalement la prise en compte des livraisons, i.e. les mises à jour successives de la base LEGI. La version 1.0 de la base de données ne pouvait pas distinguer les livraisons et il aurait alors été nécessaire de modifier directement les divers enregistrements, ce qui aurait pu corrompu la base de donnée si le programme était arrêté au cours de la mise à jour. Cette version de la base de données voit principalement l’ajout de tables pour ces livraisons, ainsi que diverses modifications mineures améliorant la cohérence.
Il y a donc deux axes d’évolution des versions manipulés par cette base de données :
- l’axe temporel (naturel) : les différentes évolutions du texte au cours du temps, par exemple les modifications d’un texte ou les différentes versions consolidées d’un code ; cet axe existait déjà dans la version 1.0 de la base de données et s’appuie entièrement sur les dates de vigueur
- l’axe des livraisons : au fur et à mesure des livraisons (tables livraison) : introduction de nouvelles versions de textes à la suite de la version la plus récente (évolution normale), réécriture de versions existantes (en cas d’erreur sur un champ, faute de frappe, etc.), ajout ou suppression de versions intermédiaires (en cas d’erreur sur les dates de vigueur)
Les deux axes d’évolution ne sont pas traités de façon identique mais s’inspirent des branches Git. Cela s’illustre par l’exemple suivant :
Axe temporel → T1 T2 T3 T4 T5 T6 T7 T8 ↓ Axe des livraisons
v1.0 v2.0 v3.0 v4.0 v5.0 -- livraison 0 : import initial
\ `v6.1 -- livraison 1 : ajout d’une nouvelle version normale
`v4.2 v5.2 v6.2 v7.2 -- livraison 2 : réécriture à partir de la version 4
`v7.3 v8.3 -- livraison 3 : introduction d’une version intermédiaire
Du fait que les livraisons peuvent ajouter des versions intermédiaires sur l’axe temporel (cf livraison 2 dans l’exemple), il peut y avoir un décalage entre les numéros d’ordre des versions et leurs dates (cf dans l’exemple v7.2 et v8.3 qui n’ont pas le même numéro d’ordre (7 et 8) mais la même date (T8). En général, lorsqu’on comparera sur l’axe des livraisons, on préférera donc les comparaisons de versions à même date plutôt qu’à même numéro d’ordre.
Les réécritures, introductions ou suppressions de versions intermédiaires peuvent être soit :
- normales : dans le cas de la manipulation des versions à venir (postérieures à la date de la livraison), lorsqu’une loi introduit une nouvelle version consolidée intermédiaire ; ou
- éditoriales : dans le cas de la manipulation des versions passées (antérieures à la date de la livraison), lorsqu’une erreur est corrigée ou que les dates de vigueur sont modifiées Cette version de la base de données ne distingue pas ces deux types de réécriture, mais cela sera probablement ajouté dans la version 3.0 de la base de données.
Modifications de la base de données par rapport à la version 1.0 :
- Ajouts, suppressions et modifications de tables :
- Ajout de la table
livraison
contenant les dates des livraisons, leur type ("fondation" (=dump complet) ou "miseajour" (=dump incrémental)) et un lien vers la livraison fondation le cas échéant - Ajout de la table
livraison_texte
mettant en correspondance les textes, livraisons et versions de texte - Ajout des tables
liste_sections
etliste_articles
listant les sections et articles inclus dans une version de texte ; ce lien était auparavant fait directement dansversion_section
etarticle
- Retrait de la table
section
, inutilisée et inutile - Renommage de la table
article
enversion_article
pour cohérence, puisque son rôle est identique àversion_section
- Ajout de la table
- Transferts de colonnes entre tables :
- De
texte
àversion_texte
:nature
,date_texte
,date_publi
: pour permettre la modification de ces champs d’une livraison à l’autre
- De
- Suppressions de colonnes :
-
version_section
/cid_id
: car suppression de la tablesection
-
version_section
/version_texte_id
etversion_article
/version_texte_id
: il faut désormais passer parliste_sections
etliste_articles
-
- Renommage de colonnes :
-
debut
etfin
renommés envigueur_debut
etvigueur_fin
: plus explicite étant donné que de multiples dates sont indiquées et manipulées - dans
version_article
,num
ennumero
: plus explicite et cohérence avecversion_section
-
- Ajout de colonnes :
-
version_texte
/date_modif
: date de dernière modification indiquée dans la base LEGI
-
- Modifications de colonnes :
- dans
version_texte
, la colonnebase_id
(référent à la première version d’un texte sur l’axe temporel) est modifiée enversion_prec_id
(référent à la version précédente sur l’axe temporel)
- dans
Les opérations classiques et prévues sur la base de données sont :
- Création ex nihilo de la base de données :
- Insertion d’une ligne dans la table
livraison
- Insertion d’une ou plusieurs lignes dans la table
texte
- Calcul des versions de texte et insertion de celles-ci dans les tables
version_{texte,section,article}
- Insertion des lignes adéquates dans les tables
livraison_texte
etliste_{sections,articles}
- Insertion d’une ligne dans la table
- Mise à jour après une mise à jour incrémentale de la base LEGI : similaire au point précédent en n’ajoutant que les versions de textes, sections et articles nécessaires et en faisant les liens adéquats dans les tables livraison
- Mise à jour après un dump complet de la base LEGI : similaire aux premier et deuxième points en n’ajoutant que ce qui n’existe pas
- Requêter toutes les versions temporelles correspondant à une livraison :
- Requête sur la table
livraison_texte
pour obtenir toutes les versions temporelles d’un texte - Requête sur la table
version_texte
pour obtenir les métadonnées sur les versions temporelles - Requête sur les tables
liste_{sections,articles}
pour obtenir les sections et articles - Requête sur les tables
version_{sections,articles}
pour obtenir les métadonnées et données sur les sections et articles
- Requête sur la table
- Requêter les versions temporelles à une date donnée pour toutes les livraisons :
- Requête sur la table
version_texte
en fixant le champvigueur_debut
(on peut aussi fixervigueur_fin
si on préfère ou même un intervalle temporel puisque la date est directement gérée par SQL) - Requête sur la table
livraison_texte
pour obtenir toutes les livraisons correspondantes à ces versions, si on veut - Requête sur les tables
liste_{sections,articles}
pour obtenir les sections et articles - Requête sur les tables
version_{sections,articles}
pour obtenir les métadonnées et données sur les sections et articles
- Requête sur la table
Noter que pour la modification, l’ajout ou la suppression d’une section, il faut créer l’enregistrement dans version_section
, puis créer des enregistrements de version_section
pour toutes les sections enfants ainsi que les articles enfants, et ceci même si ceux-ci n’ont pas été changés. Cela est requis à cause du lien id_parent_id
qui doit correspondre au nouveau élément. Je ne vois pas vraiment comment éviter cela, à part en créant une liste de sections alias, c’est-à-dire que si une section enfant a un id_parent_id
qui n’existe pas dans la liste_sections
de cette version de texte, on cherchera le bon id de section dans une table alias_section
(dans ce cas, ça serait juste pour les sections, pas pour les articles).