2017-10-20 29 views
0

Je suis occupé à retravailler un ancien programme avec Node.js et j'ai des difficultés avec le code qui ne s'exécute pas de manière synchrone.Node.js Utilisation de plusieurs niveaux SQL

La structure de la table PostgreSQL est le long des lignes de

create table tier01 (
    t01_idno integer, 
    t01_desc char(10) 
); 
insert into tier01 values 
(1, 'Tier 01 A'), 
(2, 'Tier 01 B'); 

create table tier02 (
    t02_t01_idno integer, 
    t02_idno integer, 
    t02_desc char(10) 
); 
insert into tier02 values 
(1, 1, 'Tier 02 A'), 
(1, 2, 'Tier 02 B'), 
(2, 1, 'Tier 02 A'); 

create table tier03 (
    t03_t02_idno integer, 
    t03_idno integer, 
    t03_desc char(10) 
); 
insert into tier03 values 
(1, 1, 'Tier 02 A'), 
(1, 2, 'Tier 02 B'), 
(2, 1, 'Tier 02 A'); 

Ce que je suis en train de représenter est essentiellement

select t01_desc, t02_desc, t03_desc 
from tier01, tier02, tier03 
where t01_idno = t02_t01_idno 
and t02_idno = t03_t02_idno 

Mais au lieu des résultats apparaissant comme

'Tier 01 A ','Tier 02 A ','Tier 03 A ' 
'Tier 01 A ','Tier 02 A ','Tier 03 B ' 
'Tier 01 A ','Tier 02 B ','Tier 03 A ' 
'Tier 01 B ','Tier 02 A ','Tier 03 A ' 
'Tier 01 B ','Tier 02 A ','Tier 03 B ' 

I Essaie d'obtenir

'Tier 01 A' 
- - - 'Tier 02 A' 
- - - - - - 'Tier 03 A' 
- - - - - - 'Tier 03 B' 
- - - 'Tier 02 B' 
- - - - - - 'Tier 03 A' 
'Tier 01 B' 
- - - 'Tier 02 A' 
- - - - - - 'Tier 03 A' 
- - - - - - 'Tier 03 B' 

que j'ai pu faire avec PHP sans aucun problème

//// 
// SQL 
//// 

$lv_sql = " select * from tier01 " . 
      " order by t01_idno "; 
pg_prepare($lv_db, "tier01_cur", $lv_sql); 

$lv_sql = " select * from tier02 " . 
      " where t02_t01_idno = $1 " . 
      " order by t02_idno "; 
pg_prepare($lv_db, "tier02_cur", $lv_sql); 

$lv_sql = " select * from tier03 " . 
      " where t03_t02_idno = $1 " . 
      " order by t03_idno "; 
pg_prepare($lv_db, "tier03_cur", $lv_sql); 

//// 
// Run 
//// 

// LOOP THROUGH TIER01 
$tier01_cur_query = pg_execute($lv_db, "tier01_cur", array()); 
while($tier01_cur = pg_fetch_row($tier01_cur_query)) { 

    echo '<p>' . $tier01_cur[1] . '</p>'; 

    // LOOP THROUGH TIER02 
    $tier02_cur_query = pg_execute($lv_db, "tier02_cur", array($tier01_cur[0])); 
    while($tier02_cur = pg_fetch_row($tier02_cur_query)) { 

     echo '<p> - - - ' . $tier02_cur[2] . '</p>'; 

     // LOOP THROUGH TIER03 
     $tier03_cur_query = pg_execute($lv_db, "tier03_cur", array($tier02_cur[1])); 
     while($tier03_cur = pg_fetch_row($tier03_cur_query)) { 

     echo '<p> - - - - - - ' . $tier03_cur[2] . '</p>'; 

     } 

    } 

} 

Mais je ne suis pas en mesure de reproduire les mêmes résultats avec Node.js parce que les requêtes exécutent de manière asynchrone. Je pense que je suis assez proche (ou peut-être pas du tout) en utilisant les modules async et pg mais le code semble désordonné et c'est toujours faux.

//// 
// SQL 
//// 

lv_sql = " select * from tier01 " + 
     " order by t01_idno "; 
var tier01_cur = lv_sql; 

lv_sql = " select * from tier02 " + 
     " where t02_t01_idno = $1 " + 
     " order by t02_idno "; 
var tier02_cur = lv_sql; 

lv_sql = " select * from tier03 " + 
     " where t03_t02_idno = $1 " + 
     " order by t03_idno "; 
var tier03_cur = lv_sql; 

//// 
// Run 
//// 

gv_async.series ([ 
function(series) { 

    //// 
    // CONNECT TO DATABASE 
    //// 

    lv_pgsql = l_database.client(); 

    lv_pgsql.connect(); 

    series(); 

}, 

function(series) { 

    // QUERY TIER01 
    lv_pgsql.query(tier01_cur, [], function(err, res) { 

     // LOOP THROUGH TIER01 
     gv_async.forEachOf(res.rows, function(data, cnt, callbacktier01) { 

     console.log(res.rows[cnt].t01_desc); 

     // QUERY TIER02 
     lv_pgsql.query(tier02_cur, [res.rows[cnt].t01_idno], function(err, res) { 

      // LOOP THROUGH TIER02 
      gv_async.forEachOf(res.rows, function(data, cnt, callbacktier02) { 

       console.log(" - - - " + res.rows[cnt].t02_desc); 

       // QUERY TIER03 
       lv_pgsql.query(tier03_cur, [res.rows[cnt].t02_idno], function(err, res) { 

        // LOOP THROUGH TIER03 
        gv_async.forEachOf(res.rows, function(data, cnt, callbacktier03) { 

        console.log(" - - - - - - " + res.rows[cnt].t03_desc); 
        callbacktier03(); 

        }, function(err, res) { 
        callbacktier02(); 
        }); 

       }); 

      }, function(err, res) { 
       callbacktier01(); 
      }); 

     }); 

     }, function(err, res) { 
     series(); 
     }); 

    }); 

}, 
function(series) { 

    //// 
    // DISCONNECT DATABASE 
    //// 

    lv_pgsql.end(); 

    series(); 

    // BEING CALLED WITH AJAX SO 
    // MUST SEND A RESPONSE 
    res.send(null); 

} 
]); 

Le code Node.js me donne la sortie suivante

Tier 01 A 
Tier 01 B 
- - - Tier 02 A 
- - - Tier 02 B 
- - - Tier 02 A 
- - - - - - Tier 03 A 
- - - - - - Tier 03 B 
- - - - - - Tier 03 A 
- - - - - - Tier 03 A 
- - - - - - Tier 03 B 

Je rencontre des problèmes en essayant de recréer le code synchrone destinés à un usage bien que je ne sais pas l'approche correcte Node.js pour programmer le flux comme ceci, n'importe quel conseil serait grandement apprécié

Répondre

0

Je crois que j'ai trouvé la solution, il semble fonctionner quand fait en utilisant l'async intégré et attendre (disponible à partir de la version de noeud 7.6.0) au lieu de la module npm async.

Cela semble être beaucoup plus propre et plus rapide, ce qui est tout simplement génial.

f_retrievedata(function() { 
    res.send(null); 
}); 

async function f_retrievedata(callback) { 

    var lv_sql = ""; 

    lv_sql = " select * from tier01 " + 
      " order by t01_idno "; 
    var tier01_cur = lv_sql; 

    lv_sql = " select * from tier02 " + 
      " where t02_t01_idno = $1 " + 
      " order by t02_idno "; 
    var tier02_cur = lv_sql; 

    lv_sql = " select * from tier03 " + 
      " where t03_t02_idno = $1 " + 
      " order by t03_idno "; 
    var tier03_cur = lv_sql; 

    var lr_tier01 = ""; 
    var lr_tier02 = ""; 
    var lr_tier03 = ""; 

    lv_pgsql = l_database.client(); 
    await lv_pgsql.connect(); 

    // LOOP THROUGH TIER01 
    lr_tier01 = await lv_pgsql.query(tier01_cur, []); 
    lr_tier01 = await lr_tier01.rows; 
    for(cnt1 = 0; cnt1 < lr_tier01.length; cnt1 ++) { 

      console.log(lr_tier01[cnt1].t01_desc); 

      // LOOP THROUGH TIER02 
      lr_tier02 = await lv_pgsql.query(tier02_cur, [lr_tier01[cnt1].t01_idno]); 
      lr_tier02 = await lr_tier02.rows; 
      for(cnt2 = 0; cnt2 < lr_tier02.length; cnt2 ++) { 

        console.log(" - - - " + lr_tier02[cnt2].t02_desc); 

        // LOOP THROUGH TIER03 
        lr_tier03 = await lv_pgsql.query(tier03_cur, [lr_tier02[cnt2].t02_idno]); 
        lr_tier03 = await lr_tier03.rows; 
        for(cnt3 = 0; cnt3 < lr_tier03.length; cnt3 ++) { 

          console.log(" - - - - - - " + lr_tier03[cnt3].t03_desc); 

        } 

      } 

    } 

    callback(); 

}