Commit a2c03d48 authored by Laurent Lécluse's avatar Laurent Lécluse
Browse files

Nouveau système d'installation et de mise de BDD opérationnel côté données

parent 697a793e
......@@ -27,7 +27,7 @@ $schema->create($ref, true);
/* Insertion des données */
$c->println("\n" . 'Insertion des données', $c::COLOR_LIGHT_PURPLE);
$dataGen = new DataGen($oa);
$dataGen->update();
$dataGen->install();
$c->println("\n" . 'Mise à jour du point d\'indice pour les HETD', $c::COLOR_LIGHT_PURPLE);
$bdd->exec('BEGIN OSE_FORMULE.UPDATE_ANNEE_TAUX_HETD; END;');
......
......@@ -6,11 +6,14 @@ $oa->setBdd($bdd);
/* Insertion des données */
$dataGen = new DataGen($oa);
$table = 'SCENARIO';
$table = null;
//$table = 'PARAMETRE';
$bdd->getTable($table)->delete();
//$bdd->getTable($table)->delete();
$dataGen->update($table);
$dataGen->install($table);
$r = $oa->getBdd()->getTable($table)->select();
var_dump(count($r));
\ No newline at end of file
if ($table) {
$r = $oa->getBdd()->getTable($table)->select();
var_dump(count($r));
}
\ No newline at end of file
<?php
namespace BddAdmin;
class DataGen
{
use BddAwareTrait;
const OSE_USER = 'oseappli';
/**
* @var array
*/
protected $tablesInfo = [];
protected $breaks = false;
protected $tablesSel = [
'AFFECTATION' => "utilisateur_id IN (SELECT id FROM utilisateur WHERE username='" . self::OSE_USER . "')",
'ANNEE' => '',
'CATEGORIE_PRIVILEGE' => '',
'CC_ACTIVITE' => '',
'CIVILITE' => '',
'CORPS' => '',
'DEPARTEMENT' => '',
'DISCIPLINE' => '',
'DOMAINE_FONCTIONNEL' => '',
'ETABLISSEMENT' => '',
'ETAT_VOLUME_HORAIRE' => '',
'ETAT_SORTIE' => "code IN ('winpaie', 'etat_paiement', 'export_services')",
'FONCTION_REFERENTIEL' => '',
'FORMULE' => '',
'FORMULE_TEST_INTERVENANT' => '',
'FORMULE_TEST_STRUCTURE' => '',
'FORMULE_TEST_VOLUME_HORAIRE' => '',
'GRADE' => 'corps_id in (select c.id from corps c where c.histo_destruction is null)',
'GROUPE' => '',
'IMPORT_TABLES' => '',
'INDICATEUR' => '',
'MESSAGE' => '',
'MODELE_CONTRAT' => "libelle = 'Modèle par défaut'",
'MOTIF_MODIFICATION_SERVICE' => '',
'MOTIF_NON_PAIEMENT' => '',
'PARAMETRE' => '',
'PAYS' => '',
'PERIMETRE' => '',
'PERIODE' => '',
'PLAFOND' => '',
'PLAFOND_ETAT' => '',
'PRIVILEGE' => '',
'REGLE_STRUCTURE_VALIDATION' => '',
'ROLE' => '',
'ROLE_PRIVILEGE' => '',
'SCENARIO' => 'structure_id IS NULL',
'SOURCE' => "code='OSE'",
'STATUT_INTERVENANT' => '',
'STATUT_PRIVILEGE' => 'statut_id IN (SELECT si.id FROM statut_intervenant si WHERE si.histo_destruction IS NULL)',
'TAUX_HORAIRE_HETD' => '',
'TBL' => '',
'TYPE_AGREMENT' => '',
'TYPE_AGREMENT_STATUT' => '',
'TYPE_CONTRAT' => '',
'TYPE_HEURES' => '',
'TYPE_INTERVENANT' => '',
'TYPE_INTERVENTION' => "code IN ('CM','TD','TP')",
'TYPE_PIECE_JOINTE' => '',
'TYPE_PIECE_JOINTE_STATUT' => '',
'TYPE_RESSOURCE' => '',
'TYPE_STRUCTURE' => '',
'TYPE_VALIDATION' => '',
'TYPE_VOLUME_HORAIRE' => '',
'UTILISATEUR' => "username = '" . self::OSE_USER . "'",
'WF_ETAPE' => '',
'WF_ETAPE_DEP' => '',
];
public function __construct(Bdd $bdd)
{
$this->setBdd($bdd);
}
private function makeTablesInfo()
{
$ti = [];
$sql = "
WITH refs AS (
SELECT
cc.table_name,
cc.column_name,
rcc.table_name r_table_name,
rcc.column_name r_column_name
FROM
all_constraints c
JOIN all_cons_columns cc ON cc.constraint_name = c.constraint_name AND cc.table_name = c.table_name
JOIN all_constraints rc ON rc.owner = c.owner AND rc.constraint_type = 'P' AND rc.constraint_name = c.r_constraint_name
JOIN all_cons_columns rcc ON rcc.constraint_name = rc.constraint_name AND rcc.position = cc.position
WHERE
c.constraint_type = 'R'
AND c.owner = 'OSE'
)
SELECT
utc.table_name,
utc.column_name,
utc.data_type,
refs.r_table_name,
refs.r_column_name
FROM
all_tables ut
JOIN all_tab_cols utc ON utc.owner = 'OSE' AND utc.table_name = ut.table_name
LEFT JOIN refs ON refs.table_name = utc.table_name AND refs.column_name = utc.column_name
WHERE
ut.owner = 'OSE'
AND ut.table_name <> 'WF_DEP_BLOQUANTE'
AND ut.table_name NOT LIKE 'MV_%'
AND ut.table_name NOT LIKE 'TBL_%'
AND ut.table_name NOT LIKE 'UNICAEN_%'
ORDER BY
ut.table_name,
utc.internal_column_id
";
$ts = $this->getBdd()->select($sql);
foreach ($ts as $t) {
$ti[$t['TABLE_NAME']][$t['COLUMN_NAME']] = [
'type' => $t['DATA_TYPE'],
'constraint_table' => $t['R_TABLE_NAME'],
'constraint_column' => $t['R_COLUMN_NAME'],
];
}
$tablesOk = [
'SOURCE',
];
for ($i = 0; $i < 20; $i++) {
foreach ($ti as $table => $cols) {
if (!in_array($table, $tablesOk)) {
$ok = true;
foreach ($cols as $col => $def) {
$ctable = $def['constraint_table'];
if ($ctable) {
if ((!in_array($ctable, $tablesOk)) && $ctable != $table) {
$ok = false;
}
}
}
if ($ok) {
$tablesOk[] = $table;
}
}
}
}
foreach ($ti as $table => $cols) {
if (!in_array($table, $tablesOk)) {
$tablesOk[] = $table;
}
}
$res = [];
foreach ($tablesOk as $table) {
$res[$table] = $ti[$table];
}
return $res;
}
private function getTablesInfo($tableName = null)
{
if (empty($this->tablesInfo)) {
$this->tablesInfo = $this->makeTablesInfo();
}
if ($tableName) {
return $this->tablesInfo[$tableName];
}
return $this->tablesInfo;
}
private function getCodeColumn($tableName)
{
$codesCols = [
'SOURCE_CODE',
'CODE',
'LIBELLE_COURT',
'ID',
];
if ('UTILISATEUR' == $tableName) {
return 'USERNAME';
}
$def = $this->getTablesInfo($tableName);
foreach ($codesCols as $col) {
if (isset($def[$col])) {
return $col;
}
}
throw new \Exception('Colonne de code non trouvée pour la table ' . $tableName);
}
protected function getTablesSel()
{
$roles = "('administrateur','gestionnaire-composante','superviseur-etablissement')";
$statuts = "('SALAR_ETRANGER','ENS_2ND_DEG','ENS_CH','ASS_MI_TPS','ATER','ATER_MI_TPS','DOCTOR','ENS_CONTRACT',
'LECTEUR','MAITRE_LANG','BIATSS','SALAR_PRIVE','SALAR_PUBLIC','AUTO_LIBER_INDEP','SS_EMPLOI_NON_ETUD','AUTRES',
'NON_AUTORISE')";
$ts = $this->tablesSel;
$ts['ROLE'] = "code IN $roles";
$ts['ROLE_PRIVILEGE'] = "role_id IN (SELECT id FROM role WHERE code IN $roles)";
$ts['STATUT_INTERVENANT'] = "source_code IN $statuts";
$ts['STATUT_PRIVILEGE'] = "statut_id IN (SELECT id FROM statut_intervenant WHERE source_code IN $statuts)";
$ts['TYPE_AGREMENT_STATUT'] = "statut_intervenant_id IN (SELECT id FROM statut_intervenant WHERE source_code IN $statuts)";
$ts['TYPE_PIECE_JOINTE_STATUT'] = "statut_intervenant_id IN (SELECT id FROM statut_intervenant WHERE source_code IN $statuts) AND type_piece_jointe_id IN (SELECT id FROM type_piece_jointe WHERE histo_destruction IS NULL)";
return $ts;
}
public function getDdlData()
{
$ts = $this->getTablesInfo();
$tSel = $this->getTablesSel();
$res = '';
foreach ($ts as $table => $def) {
if (isset($tSel[$table])) {
$imq = $this->makeInsertMetaQuery($table, $def, $tSel[$table]);
$res .= "\n\n-- Table $table\n";
$res .= $this->getResMetaQuery($imq);
}
}
$res .= "\n\n-- DIVERSES REQUETES SUPPLEMENTAIRES\n";
$res .= "INSERT INTO affectation(
id,
utilisateur_id,
role_id,
source_id,
histo_creation,
histo_createur_id,
histo_modification,
histo_modificateur_id
)values (
affectation_id_seq.nextval,
(select id from utilisateur where username = 'oseappli'),
(select id from role where code = 'administrateur'),
(select id from source where code = 'OSE'),
sysdate, (select id from utilisateur where username = 'oseappli'),
sysdate, (select id from utilisateur where username = 'oseappli')
);";
return $res;
}
protected function getResMetaQuery($sql)
{
$res = $this->getBdd()->select($sql);
$inserts = '';
foreach ($res as $isql) {
$inserts .= $isql['ISQL'];
}
return $inserts;
}
protected function makeInsertMetaQuery($tableName, $tableDef, $conds = '')
{
$hasHisto = isset($tableDef['HISTO_DESTRUCTION']);
$tc = [];
foreach ($tableDef as $c => $t) {
$tc[$c] = $this->formatCol($tableName, $c, $t);
}
if ($hasHisto) {
$tc['HISTO_CREATION'] = 'SYSDATE';
$tc['HISTO_CREATEUR_ID'] = '1';
$tc['HISTO_MODIFICATION'] = 'SYSDATE';
$tc['HISTO_MODIFICATEUR_ID'] = '1';
unset($tc['HISTO_DESTRUCTION']);
unset($tc['HISTO_DESTRUCTEUR_ID']);
}
$ret = $this->breaks ? "\n" : "";
$beforeColName = $this->breaks ? "\t" : "";
$beforeColValue = $this->breaks ? "\t" : "";
$isql = "SELECT 'INSERT INTO $tableName($ret" . $beforeColName
. implode(", $ret" . $beforeColName, array_keys($tc))
. "$ret) VALUES ($ret" . $beforeColValue
. implode(", $ret" . $beforeColValue, array_values($tc))
. "$ret);$ret\n' isql FROM " . $tableName . ' WHERE 1=1';
if ($hasHisto) {
$isql .= ' AND histo_destruction IS NULL';
}
if ($conds) {
$isql .= " AND ($conds)";
}
return $isql;
}
protected function formatCol($table, $column, $def)
{
if ('ID' == $column && !in_array($table, ['ANNEE', 'TYPE_VOLUME_HORAIRE', 'ETAT_VOLUME_HORAIRE', 'FORMULE', 'FORMULE_TEST_STRUCTURE', 'PLAFOND', 'FORMULE_TEST_INTERVENANT','FORMULE_TEST_VOLUME_HORAIRE'])) {
return substr($table, 0, 23) . '_ID_SEQ.NEXTVAL';
}
if ('SOURCE_ID' == $column) {
return "(SELECT id FROM source WHERE code = ''OSE'')";
}
if ('DEBUG_INFO' == $column && 'FORMULE_TEST_INTERVENANT' == $table) {
return 'NULL';
}
if ('DEBUG_INFO' == $column && 'FORMULE_TEST_VOLUME_HORAIRE' == $table) {
return 'NULL';
}
if ('TYPE_HEURES_ELEMENT_ID' == $column && 'TYPE_HEURES' == $table) {
return 'TYPE_HEURES_ID_SEQ.CURRVAL';
}
if ('PRIVILEGE_ID' == $column) {
$cppSql = "SELECT cp.code || '-' || p.code FROM privilege p JOIN categorie_privilege cp ON cp.id = p.categorie_id WHERE p.id = privilege_id";
return "(SELECT p.id FROM privilege p JOIN categorie_privilege cp ON p.categorie_id = cp.id WHERE cp.code || ''-'' || p.code = ''' ||($cppSql)|| ''')";
}
if ('ROLE_ID' == $column && $table == 'AFFECTATION') {
return "(SELECT id FROM role WHERE code = ''administrateur'')";
}
if ('PASSWORD' == $column && $table == 'UTILISATEUR') {
return "''x''";
}
if ('IMPORT_TABLES' == $table && 'SYNC_ENABLED' == $column) {
return '0';
}
if ('ETAT_SORTIE' == $table && 'PDF_TRAITEMENT' == $column) {
return "' || CASE WHEN code='etat_paiement' THEN '''/data/Etats de sortie/etat_paiement.php''' ELSE 'NULL' END || '";
}
if ($def['constraint_table']) {
$ctable = $def['constraint_table'];
$ccol = $def['constraint_column'];
$codeCol = $this->getCodeColumn($ctable);
$ccsql = "SELECT $codeCol FROM $ctable WHERE $ccol = $column";
$csql = "'(SELECT $ccol FROM $ctable WHERE ROWNUM = 1 AND $codeCol = q''[' || ($ccsql) || ']'')'";
return "' || CASE WHEN $column IS NULL THEN 'NULL' ELSE $csql END || '";
}
switch ($def['type']) {
case 'NUMBER':
case 'FLOAT':
return "' || CASE WHEN $column IS NULL THEN 'NULL' ELSE '' || $column || '' END || '";
break;
case 'VARCHAR2':
return "' || CASE WHEN $column IS NULL THEN 'NULL' ELSE 'q''[' || $column || ']''' END || '";
case 'CLOB':
return "' || CASE WHEN $column IS NULL THEN 'NULL' ELSE 'q''[' || to_char($column) || ']''' END || '";
case 'BLOB':
return 'NULL';
case 'DATE':
return "' || CASE WHEN $column IS NULL THEN 'NULL' ELSE 'to_date(''' || to_char($column,'YYYY-MM-DD HH:MI:SS') || ''',''YYYY-MM-DD HH:MI:SS'')' END || '";
}
return $column;
}
}
......@@ -181,7 +181,7 @@ class Table
*
* @return bool
*/
public function delete($where=null, array $options = []): bool
public function delete($where = null, array $options = []): bool
{
$params = [];
$sql = "DELETE FROM \"$this->name\"" . $this->makeWhere($where, $options, $params);
......@@ -327,9 +327,22 @@ class Table
*/
private function makeWhere($where, array $options, array &$params): string
{
if ($where && !is_array($where) && $this->hasId()) {
$where = ['ID' => $where];
if (is_string($where) && (
false !== strpos($where, '=')
|| false !== strpos($where, ' IN ')
|| false !== strpos($where, ' IN(')
|| false !== strpos($where, ' IS ')
|| false !== strpos($where, ' NOT ')
|| false !== strpos($where, '<')
|| false !== strpos($where, '>')
)
) {
return ' WHERE '.$where;
}
if ($where && !is_array($where) && $this->hasId()) {
$where = ['ID' => $where];
}
if ($where) {
$whereSql = '';
......@@ -340,15 +353,15 @@ class Table
if (isset($options['columns'][$c]['transformer'])) {
$transVal = ':' . $c;
$transVal = '(' . sprintf($options['columns'][$c]['transformer'], $transVal) . ')';
$transVal = ':' . $c;
$transVal = '(' . sprintf($options['columns'][$c]['transformer'], $transVal) . ')';
$whereSql .= $c . ' = ' . $transVal;
$params[$c] = $v;
}else{
if ($v === null){
$whereSql .= $c . ' IS NULL';
}else{
$transVal = ':' . $c;
} else {
if ($v === null) {
$whereSql .= $c . ' IS NULL';
} else {
$transVal = ':' . $c;
$whereSql .= $c . ' = ' . $transVal;
$params[$c] = $v;
}
......@@ -390,10 +403,10 @@ class Table
protected function transform($value, string $transformer, array $ddl)
{
if (!isset($this->transformCache[$transformer][$value])) {
$val = $this->getBdd()->select(sprintf($transformer, ':val'), ['val' => $value]);
if (isset($val[0])){
$val = $this->getBdd()->select(sprintf($transformer, ':val'), ['val' => $value]);
if (isset($val[0])) {
$this->transformCache[$transformer][$value] = $this->sqlToVal(current($val[0]), $ddl);
}else{
} else {
$this->transformCache[$transformer][$value] = null;
}
}
......@@ -405,6 +418,8 @@ class Table
protected function sqlToVal($value, array $ddl)
{
if ($value === null) return null;
switch ($ddl['type']) {
case 'NUMBER':
if (1 == $ddl['precision']) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
-- Script de migration de la version 6.2.2 à 6.3
ALTER TABLE effectifs MODIFY (
element_pedagogique_id NOT NULL
);
DROP VIEW V_TYPE_INTERVENTION_REGLE_EP;
ALTER TABLE import_tables ADD (
ordre NUMBER
);
ALTER TABLE import_tables ADD (
sync_job VARCHAR2(40 CHAR)
);
ALTER TABLE import_tables ADD (
sync_hook_before VARCHAR2(4000 CHAR)
);
ALTER TABLE import_tables ADD (
sync_hook_after VARCHAR2(4000 CHAR)
);
UPDATE import_tables SET ordre = 1 WHERE table_name = 'PAYS';
UPDATE import_tables SET ordre = 2 WHERE table_name = 'DEPARTEMENT';
UPDATE import_tables SET ordre = 3 WHERE table_name = 'ETABLISSEMENT';
UPDATE import_tables SET ordre = 4 WHERE table_name = 'STRUCTURE';
UPDATE import_tables SET ordre = 5 WHERE table_name = 'ADRESSE_STRUCTURE';
UPDATE import_tables SET ordre = 6 WHERE table_name = 'DOMAINE_FONCTIONNEL';
UPDATE import_tables SET ordre = 7 WHERE table_name = 'CENTRE_COUT';
UPDATE import_tables SET ordre = 8 WHERE table_name = 'CENTRE_COUT_STRUCTURE';
UPDATE import_tables SET ordre = 9 WHERE table_name = 'AFFECTATION';
UPDATE import_tables SET ordre = 10 WHERE table_name = 'CORPS';
UPDATE import_tables SET ordre = 11 WHERE table_name = 'GRADE';
UPDATE import_tables SET ordre = 12 WHERE table_name = 'INTERVENANT';
UPDATE import_tables SET ordre = 13 WHERE table_name = 'AFFECTATION_RECHERCHE';
UPDATE import_tables SET ordre = 14 WHERE table_name = 'ADRESSE_INTERVENANT';
UPDATE import_tables SET ordre = 15 WHERE table_name = 'GROUPE_TYPE_FORMATION';
UPDATE import_tables SET ordre = 16 WHERE table_name = 'TYPE_FORMATION';
UPDATE import_tables SET ordre = 17 WHERE table_name = 'ETAPE';
UPDATE import_tables SET ordre = 18 WHERE table_name = 'ELEMENT_PEDAGOGIQUE';
UPDATE import_tables SET ordre = 19 WHERE table_name = 'EFFECTIFS';
UPDATE import_tables SET ordre = 20 WHERE table_name = 'ELEMENT_TAUX_REGIMES';
UPDATE import_tables SET ordre = 21 WHERE table_name = 'CHEMIN_PEDAGOGIQUE';
UPDATE import_tables SET ordre = 22 WHERE table_name = 'VOLUME_HORAIRE_ENS';
UPDATE import_tables SET ordre = 23 WHERE table_name = 'NOEUD';
UPDATE import_tables SET ordre = 24 WHERE table_name = 'LIEN';
UPDATE import_tables SET ordre = 25 WHERE table_name = 'SCENARIO_LIEN';
UPDATE import_tables SET ordre = 26 WHERE table_name = 'TYPE_INTERVENTION_EP';
UPDATE import_tables SET ordre = 27 WHERE table_name = 'TYPE_MODULATEUR_EP';
UPDATE import_tables SET sync_job = 'synchro' WHERE table_name IN (
'PAYS','DEPARTEMENT','ETABLISSEMENT','STRUCTURE','ADRESSE_STRUCTURE','DOMAINE_FONCTIONNEL','CENTRE_COUT',
'CENTRE_COUT_STRUCTURE','AFFECTATION','CORPS','GRADE','INTERVENANT','AFFECTATION_RECHERCHE',
'ADRESSE_INTERVENANT','GROUPE_TYPE_FORMATION','TYPE_FORMATION','ETAPE','ELEMENT_PEDAGOGIQUE','EFFECTIFS',
'CHEMIN_PEDAGOGIQUE','VOLUME_HORAIRE_ENS','NOEUD','LIEN','SCENARIO_LIEN','TYPE_INTERVENTION_EP',
'TYPE_MODULATEUR_EP');
UPDATE IMPORT_TABLES SET SYNC_HOOK_BEFORE = 'UNICAEN_IMPORT.REFRESH_MV(''MV_AFFECTATION'');
/* Import automatique des users des nouveaux directeurs */
INSERT INTO utilisateur (
id, display_name, email, password, state, username
)
SELECT
utilisateur_id_seq.nextval id,
aff.*
FROM
(SELECT DISTINCT display_name, email, password, state, username FROM mv_affectation) aff
WHERE
username not in (select username from utilisateur);' WHERE table_name = 'AFFECTATION';
UPDATE IMPORT_TABLES SET SYNC_FILTRE = 'WHERE (
IMPORT_ACTION IN (''delete'',''update'',''undelete'')
OR STATUT_ID IN (
SELECT si.id
FROM statut_intervenant si
JOIN type_intervenant ti ON ti.id = si.type_intervenant_id
WHERE ti.code = ''P''
)
)', SYNC_HOOK_BEFORE = 'UNICAEN_IMPORT.REFRESH_MV(''MV_UNICAEN_STRUCTURE_CODES'');
UNICAEN_IMPORT.REFRESH_MV(''MV_INTERVENANT'');' WHERE table_name = 'INTERVENANT';
UPDATE IMPORT_TABLES SET SYNC_FILTRE = 'WHERE INTERVENANT_ID IS NOT NULL' WHERE table_name IN ('AFFECTATION_RECHERCHE','ADRESSE_INTERVENANT');
UPDATE IMPORT_TABLES SET SYNC_FILTRE = 'WHERE IMPORT_ACTION IN (''delete'',''insert'',''undelete'')' WHERE table_name = 'ELEMENT_TAUX_REGIMES';
UPDATE IMPORT_TABLES SET SYNC_HOOK_AFTER = 'UNICAEN_IMPORT.REFRESH_MV(''TBL_NOEUD'');
UNICAEN_TBL.CALCULER(''chargens'');' WHERE table_name = 'NOEUD';