Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
laboratoare:laborator06 [2015/11/30 02:15]
Andrei Roșu-Cojocaru [Gestiunea Obiectelor Cerere / Răspuns]
laboratoare:laborator06 [2015/11/30 15:31] (current)
Andrei Roșu-Cojocaru
Line 134: Line 134:
   * ''​cale'':​ se va folosi o versiune disponibilă la o locație în sistemul local de fișiere.   * ''​cale'':​ se va folosi o versiune disponibilă la o locație în sistemul local de fișiere.
  
-<​code>​+<​code ​json>
 ... ...
 "​dependencies":​ { "​dependencies":​ {
Line 203: Line 203:
 Pentru o metodă, un apel sincron (blocant) ar putea fi: Pentru o metodă, un apel sincron (blocant) ar putea fi:
  
-<​code>​+<​code ​javascript>
 var result = syncMethod(param);​ var result = syncMethod(param);​
 console.log(result);​ console.log(result);​
Line 213: Line 213:
 O variantă asincronă (non-blocantă) ar putea fi: O variantă asincronă (non-blocantă) ar putea fi:
  
-<​code>​+<​code ​javascript>
 asyncMethod(param,​ function(error,​ result) { asyncMethod(param,​ function(error,​ result) {
   if (error) {   if (error) {
Line 235: Line 235:
 Modulul [[https://​nodejs.org/​api/​events.html|events]] permite utilizarea de evenimente definite de utilizator. Un astfel de comportament este util mai ales în situația în care apelul mai multor metode trebuie sincronizat,​ pentru a se asigura faptul că acestea sunt executate secvențial. Pentru utilizarea funcționalității oferite de acest modul, este necesar ca acesta să fie importat, instanțiindu-se un obiect de tipul [[https://​nodejs.org/​api/​events.html#​events_class_events_eventemitter|events.EventEmitter]]. Modulul [[https://​nodejs.org/​api/​events.html|events]] permite utilizarea de evenimente definite de utilizator. Un astfel de comportament este util mai ales în situația în care apelul mai multor metode trebuie sincronizat,​ pentru a se asigura faptul că acestea sunt executate secvențial. Pentru utilizarea funcționalității oferite de acest modul, este necesar ca acesta să fie importat, instanțiindu-se un obiect de tipul [[https://​nodejs.org/​api/​events.html#​events_class_events_eventemitter|events.EventEmitter]].
  
-<​code>​+<​code ​javascript>
 var events = require('​events'​);​ var events = require('​events'​);​
 var eventEmitter = new events.EventEmitter();​ var eventEmitter = new events.EventEmitter();​
Line 242: Line 242:
 Un eveniment este generat în momentul în care se apelează metoda [[https://​nodejs.org/​api/​events.html#​events_emitter_emit_event_arg1_arg2|emit()]]. Aceasta primește ca parametri denumirea evenimentului,​ precum și alte argumente care vor fi transmise funcției de tip callback, atașate ascultătorului specific evenimentului respectiv. Un eveniment este generat în momentul în care se apelează metoda [[https://​nodejs.org/​api/​events.html#​events_emitter_emit_event_arg1_arg2|emit()]]. Aceasta primește ca parametri denumirea evenimentului,​ precum și alte argumente care vor fi transmise funcției de tip callback, atașate ascultătorului specific evenimentului respectiv.
  
-<​code>​+<​code ​javascript>
 eventEmitter.emit('​someEvent'​);​ eventEmitter.emit('​someEvent'​);​
 </​code>​ </​code>​
Line 248: Line 248:
 Metoda furnizează rezultatul ''​true''​ în situația în care au fost înregistrați în prealabil ascultători și ''​false'',​ în caz contrar. Această operație este realizată prin metodele [[https://​nodejs.org/​api/​events.html#​events_emitter_on_event_listener|on()]],​ respectiv [[https://​nodejs.org/​api/​events.html#​events_emitter_addlistener_event_listener|addListener()]] (echivalente),​ fiecare dintre acestea primind ca parametri denumirea evenimentului precum și funcția de tip callback. Metoda furnizează rezultatul ''​true''​ în situația în care au fost înregistrați în prealabil ascultători și ''​false'',​ în caz contrar. Această operație este realizată prin metodele [[https://​nodejs.org/​api/​events.html#​events_emitter_on_event_listener|on()]],​ respectiv [[https://​nodejs.org/​api/​events.html#​events_emitter_addlistener_event_listener|addListener()]] (echivalente),​ fiecare dintre acestea primind ca parametri denumirea evenimentului precum și funcția de tip callback.
  
-<​code>​+<​code ​javascript>
 var someEventHandler = function process() ​ { var someEventHandler = function process() ​ {
   console.log('​processing...'​);​   console.log('​processing...'​);​
Line 277: Line 277:
 În situația în care trebuie procesate elementele unei liste (x<​sub>​1</​sub>,​ x<​sub>​2</​sub>,​ ..., x<​sub>​n</​sub>​),​ iar procesarea fiecărui element trebuie realizată secvențial (x<​sub>​1</​sub>​ < x<​sub>​2</​sub>​ < ... < x<​sub>​n</​sub>​),​ o abordare folosind un iterator clasic și o metodă asincronă ce operează pe elementul respectiv nu este viabilă (întrucât referința către acesta se poate schimba până la momentul în care este executată metoda asincronă). În situația în care trebuie procesate elementele unei liste (x<​sub>​1</​sub>,​ x<​sub>​2</​sub>,​ ..., x<​sub>​n</​sub>​),​ iar procesarea fiecărui element trebuie realizată secvențial (x<​sub>​1</​sub>​ < x<​sub>​2</​sub>​ < ... < x<​sub>​n</​sub>​),​ o abordare folosind un iterator clasic și o metodă asincronă ce operează pe elementul respectiv nu este viabilă (întrucât referința către acesta se poate schimba până la momentul în care este executată metoda asincronă).
  
-<​code>​+<​code ​javascript>
 for (var index = 1; index <= someList.length;​ index++) { for (var index = 1; index <= someList.length;​ index++) {
   someAsyncMethod(parameter,​ function(error,​ result) {   someAsyncMethod(parameter,​ function(error,​ result) {
Line 293: Line 293:
   - se generează un eveniment de procesare a primului element al listei.   - se generează un eveniment de procesare a primului element al listei.
  
-<​code>​+<​code ​javascript>
 var someEventHandler = function someProcessing(index) { var someEventHandler = function someProcessing(index) {
   if (index > someList.length) {   if (index > someList.length) {
Line 343: Line 343:
 Utilizarea unui flux de intrare implică definirea unui comportament pentru evenimentele ''​data''​ și ''​end''​ (eventual ''​error''​). Utilizarea unui flux de intrare implică definirea unui comportament pentru evenimentele ''​data''​ și ''​end''​ (eventual ''​error''​).
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
 var data = '';​ var data = '';​
Line 367: Line 367:
 Alternativ, se poate utiliza evenimentul ''​readable''​ împreună cu metoda [[https://​nodejs.org/​api/​stream.html#​stream_readable_read_size|read()]] care primește ca parametru opțional un număr indicând dimensiunea (exprimată în octeți) care se așteaptă a fi citită (în situația în care nu este disponibilă cantitatea respectivă se întoarce ''​null'',​ cu excepția situației în care nu mai sunt alte date disponibile);​ în situația în care nu se furnizează nici un argument, se întoarce întreaga cantitate disponibilă. Alternativ, se poate utiliza evenimentul ''​readable''​ împreună cu metoda [[https://​nodejs.org/​api/​stream.html#​stream_readable_read_size|read()]] care primește ca parametru opțional un număr indicând dimensiunea (exprimată în octeți) care se așteaptă a fi citită (în situația în care nu este disponibilă cantitatea respectivă se întoarce ''​null'',​ cu excepția situației în care nu mai sunt alte date disponibile);​ în situația în care nu se furnizează nici un argument, se întoarce întreaga cantitate disponibilă.
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
 var data = '';​ var data = '';​
Line 394: Line 394:
 Utilizarea unui flux de ieșirea implică apelul metodelor [[https://​nodejs.org/​api/​stream.html#​stream_writable_write_chunk_encoding_callback|write()]] respectiv [[https://​nodejs.org/​api/​stream.html#​stream_writable_end_chunk_encoding_callback|end()]] precum și definirea unui comportament pentru evenimentul ''​end''​ (eventual ''​error''​). Ambele metode primesc ca parametri datele care se doresc a fi scrise, tipul de codificare folosit precum și o funcție de tip callback care este apelată în momentul în care datele au fost transmise complet. Apelul metodei ''​write()''​ după ce anterior s-a invocat metoda ''​end()''​ nu este permis și va genera o eroare. Utilizarea unui flux de ieșirea implică apelul metodelor [[https://​nodejs.org/​api/​stream.html#​stream_writable_write_chunk_encoding_callback|write()]] respectiv [[https://​nodejs.org/​api/​stream.html#​stream_writable_end_chunk_encoding_callback|end()]] precum și definirea unui comportament pentru evenimentul ''​end''​ (eventual ''​error''​). Ambele metode primesc ca parametri datele care se doresc a fi scrise, tipul de codificare folosit precum și o funcție de tip callback care este apelată în momentul în care datele au fost transmise complet. Apelul metodei ''​write()''​ după ce anterior s-a invocat metoda ''​end()''​ nu este permis și va genera o eroare.
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
 var data = 'Some Data'; var data = 'Some Data';
Line 415: Line 415:
 Un flux de intrare poate fi atașat unui flux de ieșire prin intermediul metodei [[https://​nodejs.org/​api/​stream.html#​stream_readable_pipe_destination_options|pipe()]]. În acest mod, conținutul din sursa de date este transferată în mod automat în destinația de date. Metoda se apelează pe fluxul de intrare și primește ca parametru fluxul de ieșire, specificându-se eventual și un set de opțiuni (atributul ''​end'',​ având implicit valoarea ''​true'',​ indică faptul că fluxul de ieșire nu mai poate fi utilizat după ce datele din fluxul de intrare au fost transferate). O astfel de metodă este utilă pentru că  adaptează transferul de date astfel încât să fie adecvate vitezelor de transfer ale fluxurilor de date de tip intrare, respectiv ieșire. Similar, se poate folosi metoda [[https://​nodejs.org/​api/​stream.html#​stream_readable_unpipe_destination|unpipe()]] care detașează fluxul de ieșire de la fluxul de intrare, în situația în care s-a produs o eroare sau a expirat un timp limită pentru transferul de date. Metoda se apelează pe fluxul de intrare și poate primi ca parametru opțional fluxul de ieșire (în caz contrar, fiind detașate toate fluxurile de ieșire). Un flux de intrare poate fi atașat unui flux de ieșire prin intermediul metodei [[https://​nodejs.org/​api/​stream.html#​stream_readable_pipe_destination_options|pipe()]]. În acest mod, conținutul din sursa de date este transferată în mod automat în destinația de date. Metoda se apelează pe fluxul de intrare și primește ca parametru fluxul de ieșire, specificându-se eventual și un set de opțiuni (atributul ''​end'',​ având implicit valoarea ''​true'',​ indică faptul că fluxul de ieșire nu mai poate fi utilizat după ce datele din fluxul de intrare au fost transferate). O astfel de metodă este utilă pentru că  adaptează transferul de date astfel încât să fie adecvate vitezelor de transfer ale fluxurilor de date de tip intrare, respectiv ieșire. Similar, se poate folosi metoda [[https://​nodejs.org/​api/​stream.html#​stream_readable_unpipe_destination|unpipe()]] care detașează fluxul de ieșire de la fluxul de intrare, în situația în care s-a produs o eroare sau a expirat un timp limită pentru transferul de date. Metoda se apelează pe fluxul de intrare și poate primi ca parametru opțional fluxul de ieșire (în caz contrar, fiind detașate toate fluxurile de ieșire).
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
  
Line 434: Line 434:
 <columns 100% 50%> <columns 100% 50%>
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
 var zlib = require('​zlib'​);​ var zlib = require('​zlib'​);​
Line 450: Line 450:
 <​newcolumn>​ <​newcolumn>​
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
 var zlib = require('​zlib'​);​ var zlib = require('​zlib'​);​
Line 529: Line 529:
   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care fișierul este deschis, primind ca argumente o eroare (în cazul în care se produce) și descriptorul pentru fișier.   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care fișierul este deschis, primind ca argumente o eroare (în cazul în care se produce) și descriptorul pentru fișier.
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
  
Line 551: Line 551:
   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care fișierul este închis, primind ca argumente o eroare (în cazul în care se produce).   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care fișierul este închis, primind ca argumente o eroare (în cazul în care se produce).
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
  
Line 583: Line 583:
 | ''​isSocket()''​ | întoarce ''​true''​ dacă tipul resursei este un socket | | ''​isSocket()''​ | întoarce ''​true''​ dacă tipul resursei este un socket |
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
  
Line 609: Line 609:
   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat o operație de citire din fișier, primind ca argumente o eroare (în cazul în care se produce), numărul de octeți care au fost citiți și un obiect de tip ''​Buffer''​ în care poate fi accesat conținutul respectiv.   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat o operație de citire din fișier, primind ca argumente o eroare (în cazul în care se produce), numărul de octeți care au fost citiți și un obiect de tip ''​Buffer''​ în care poate fi accesat conținutul respectiv.
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
 var buffer = new Buffer(1024);​ var buffer = new Buffer(1024);​
Line 644: Line 644:
   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat o operație de scriere în fișier, primind ca argumente o eroare (în cazul în care se produce).   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat o operație de scriere în fișier, primind ca argumente o eroare (în cazul în care se produce).
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
  
Line 666: Line 666:
   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat o operația de modificare a fișierului,​ primind ca argumente o eroare (în cazul în care se produce).   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat o operația de modificare a fișierului,​ primind ca argumente o eroare (în cazul în care se produce).
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
 var buffer = new Buffer(1024);​ var buffer = new Buffer(1024);​
Line 708: Line 708:
   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat o operație de scriere în fișier, primind ca argumente o eroare (în cazul în care se produce).   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat o operație de scriere în fișier, primind ca argumente o eroare (în cazul în care se produce).
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
  
Line 732: Line 732:
   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat operația de creare a directorului,​ primind ca argument o eroare (în cazul în care se produce).   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat operația de creare a directorului,​ primind ca argument o eroare (în cazul în care se produce).
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
  
Line 753: Line 753:
   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat operația de ștergere a directorului,​ primind ca argument o eroare (în cazul în care se produce).   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-a realizat operația de ștergere a directorului,​ primind ca argument o eroare (în cazul în care se produce).
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
  
Line 774: Line 774:
   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-au obținut informații cu privire la director, primind ca argument o eroare (în cazul în care se produce) și o listă de fișiere conținute în cadrul directorului (exclusiv ''​.''​ și ''​..''​).   * ''​callback''​ - funcția de tip callback care este invocată în momentul în care s-au obținut informații cu privire la director, primind ca argument o eroare (în cazul în care se produce) și o listă de fișiere conținute în cadrul directorului (exclusiv ''​.''​ și ''​..''​).
  
-<​code>​+<​code ​javascript>
 var fs = require('​fs'​);​ var fs = require('​fs'​);​
  
Line 798: Line 798:
 | [[https://​nodejs.org/​api/​globals.html#​globals_filename|__filename]] | locația (cale absolută) la care se găsește fișierul care este executat în mod curent | | [[https://​nodejs.org/​api/​globals.html#​globals_filename|__filename]] | locația (cale absolută) la care se găsește fișierul care este executat în mod curent |
 | [[https://​nodejs.org/​api/​globals.html#​globals_dirname|__dirname]] | locația (cale absolută) la care se găsește directorul din care face parte fișierul care este executat în mod curent | | [[https://​nodejs.org/​api/​globals.html#​globals_dirname|__dirname]] | locația (cale absolută) la care se găsește directorul din care face parte fișierul care este executat în mod curent |
-| [[https://​nodejs.org/​api/​globals.html#​globals_settimeout_cb_ms|setTimeout(cb,​ms)]] | utilizată pentru a invoca o funcție de tip callback după o anumită durată; momentul la care va fi executată metoda propriu-zis depinde de modul în care este configurat sistemul de operare precum și de încărcarea mașinii pe care acesta este rulat <​code>​+| [[https://​nodejs.org/​api/​globals.html#​globals_settimeout_cb_ms|setTimeout(cb,​ms)]] | utilizată pentru a invoca o funcție de tip callback după o anumită durată; momentul la care va fi executată metoda propriu-zis depinde de modul în care este configurat sistemul de operare precum și de încărcarea mașinii pe care acesta este rulat <​code ​javascript>
 var timeout = setTimeout(function() { var timeout = setTimeout(function() {
   console.log('​this is a message'​_'​);​   console.log('​this is a message'​_'​);​
 }, 1000); }, 1000);
 </​code>​ | </​code>​ |
-| [[https://​nodejs.org/​api/​globals.html#​globals_cleartimeout_t|clearTimeout(t)]] | utilizată pentru a opri invocarea unei funcții de tip callback după o anumită durată; <​code>​+| [[https://​nodejs.org/​api/​globals.html#​globals_cleartimeout_t|clearTimeout(t)]] | utilizată pentru a opri invocarea unei funcții de tip callback după o anumită durată; <​code ​javascript>
 clearTimeout(timeout);​ clearTimeout(timeout);​
 </​code>​ | </​code>​ |
-| [[https://​nodejs.org/​api/​globals.html#​globals_setinterval_cb_ms|setInterval(cb,​ms)]] | utilizată pentru a invoca o funcție de tip callback periodic, la un anumit interval; momentul la care va fi executată metoda propriu-zis depinde de modul în care este configurat sistemul de operare precum și de încărcarea mașinii pe care acesta este rulat <​code>​+| [[https://​nodejs.org/​api/​globals.html#​globals_setinterval_cb_ms|setInterval(cb,​ms)]] | utilizată pentru a invoca o funcție de tip callback periodic, la un anumit interval; momentul la care va fi executată metoda propriu-zis depinde de modul în care este configurat sistemul de operare precum și de încărcarea mașinii pe care acesta este rulat <​code ​javascript>
 var interval = setInterval(function() { var interval = setInterval(function() {
   console.log('​this is a message'​_'​);​   console.log('​this is a message'​_'​);​
 }, 1000); }, 1000);
 </​code>​ | </​code>​ |
-| [[https://​nodejs.org/​api/​globals.html#​globals_clearinterval_t|clearInterval(t)]] | utilizată pentru a opri invocarea unei funcții de tip callback periodic, la un anumit interval; <​code>​+| [[https://​nodejs.org/​api/​globals.html#​globals_clearinterval_t|clearInterval(t)]] | utilizată pentru a opri invocarea unei funcții de tip callback periodic, la un anumit interval; <​code ​javascript>
 clearInterval(interval);​ clearInterval(interval);​
 </​code>​ | </​code>​ |
Line 854: Line 854:
   - va lansa în execuție aplicația web printr-un apel al metodei ''​listen()''​ care primește ca parametri portul pe care aplicația este accesibilă precum și o funcție de tip callback invocată în momentul în care aplicația web rulează).   - va lansa în execuție aplicația web printr-un apel al metodei ''​listen()''​ care primește ca parametri portul pe care aplicația este accesibilă precum și o funcție de tip callback invocată în momentul în care aplicația web rulează).
  
-<​code>​+<​code ​javascript>
 var express = require('​express'​);​ var express = require('​express'​);​
 var app = express(); var app = express();
Line 880: Line 880:
 Astfel, metoda ''​use()''​ va primi ca parametru rezultatul funcției ''​express.static()''​ căreia i se va transmite ca argument locația la care se găsesc resursele care vor putea fi referite direct din navigator (întrucât referirea se face relativ la denumirea directorului static, acesta nu va fi inclus în URL atunci când se încearcă regăsirea informațiilor respective). Astfel, metoda ''​use()''​ va primi ca parametru rezultatul funcției ''​express.static()''​ căreia i se va transmite ca argument locația la care se găsesc resursele care vor putea fi referite direct din navigator (întrucât referirea se face relativ la denumirea directorului static, acesta nu va fi inclus în URL atunci când se încearcă regăsirea informațiilor respective).
  
-<​code>​+<​code ​javascript>
 var express = require('​express'​);​ var express = require('​express'​);​
 var app = express(); var app = express();
Line 994: Line 994:
   * ''​view engine''​ precizează motorul care va fi utilizat pentru redarea acestor fișiere.   * ''​view engine''​ precizează motorul care va fi utilizat pentru redarea acestor fișiere.
  
-<​code>​+<​code ​javascript>
 var express = require('​express'​);​ var express = require('​express'​);​
 var app = express(); var app = express();
Line 1133: Line 1133:
   * ''​trace''​ - permite reținerea stivei de execuție în cadrul obiectelor ''​Error''​ care să includă apelul metodei din cadrul bibliotecii,​ cu deprecieri ale performanțelor pentru majoritatea apelurilor (implicit, ''​true''​);​   * ''​trace''​ - permite reținerea stivei de execuție în cadrul obiectelor ''​Error''​ care să includă apelul metodei din cadrul bibliotecii,​ cu deprecieri ale performanțelor pentru majoritatea apelurilor (implicit, ''​true''​);​
   * ''​multipleStatements''​ - stabilește comportamentul în privința utilizării mai multor expresii MySQL în cadrul aceleiași interogări,​ ceea ce ar putea reprezenta o breșă de securitate în privința atacurilor prin injecția de SQL malițios (implicit, ''​false''​);​   * ''​multipleStatements''​ - stabilește comportamentul în privința utilizării mai multor expresii MySQL în cadrul aceleiași interogări,​ ceea ce ar putea reprezenta o breșă de securitate în privința atacurilor prin injecția de SQL malițios (implicit, ''​false''​);​
-  * ''​flags''​ - stabilește o listă cu valori care vor controla comportamentul conexiunii;+  * ''​flags''​ - stabilește o listă cu valori care vor controla comportamentul conexiunii; aceștia sunt transmiși sub forma unui șir de caractere în care delimitatorul este caracterul '','';​ un flag care este adăugat în plus față de cele implicite trebuie prefixat de caracterul ''​+''​ iar în situația în care se dorește ca un flag implicit să fie șters, acesta trebuie prefixat de caracterul ''​-'';​ lista de flag-uri implicite este: 
 +    * ''​CONNECT_WITH_DB''​ - permite specificarea denumirii bazei de date în momentul în care este definită o conexiune;​ 
 +    * ''​FOUND_ROWS''​ - transmite atributul ''​found_rows''​ al argumentului ''​result''​ din cadrul metodei de tip callback transmisă prin metoda ''​query()'',​ în loc de ''​affected_rows'';​ 
 +    * ''​IGNORE_SPACE''​ - interpretorul SQL va ignora spațiile care preced caracterul ''​(''​ în cadrul interogărilor;​ 
 +    * ''​LOCAL_FILES''​ - permite încărcarea înregistrărilor într-o bază de date folosind ''​LOAD DATA LOCAL'';​ 
 +    * ''​LONG_FLAG'';​ 
 +    * ''​LONG_PASSWORD''​ - folosește o versiune îmbunătățită a mecanismului de autentificare;​ 
 +    * ''​MULTI_RESULTS''​ - semnalează posibilitatea de gestiune concurentă a mai multe seturi de rezultate;​ 
 +    * ''​PROTOCOL_41''​ - folosește versiunea 4.1 a protocolului de conectare la baza de date; 
 +    * ''​PS_MULTI_RESULTS''​ - semnalează posibilitatea de gestiune concurentă a mai multe seturi de rezultate;​ 
 +    * ''​SECURE_CONNECTION''​ - indică faptul că este suportată mecanismul de autentificare nativ din versiunea 4.1 a protocolului de conectare la baza de date; 
 +    * ''​TRANSACTIONS''​ - solicită utilizarea flag-urilor care indică starea tranzacției;​ 
 +    * ''​MULTI_STATEMENTS''​ - transmis în mod automat în situația în care parametrul ''​multipleStatements''​ are valoarea ''​true''​;
   * ''​ssl''​ - transmite un obiect care conține parametri SSL sau un șir de caracyere care conține denumirea unui profil SSL.   * ''​ssl''​ - transmite un obiect care conține parametri SSL sau un șir de caracyere care conține denumirea unui profil SSL.
  
Line 1167: Line 1179:
   * metoda ''​destroy()''​ determină o terminare imediată a legăturii cu sistemul de gestiune pentru baze de date, garantând faptul că nu se vor mai produce alte evenimente și nici nu vor fi invocate metode de tip callback legate de conexiunea în cauză: <code javascript>​   * metoda ''​destroy()''​ determină o terminare imediată a legăturii cu sistemul de gestiune pentru baze de date, garantând faptul că nu se vor mai produce alte evenimente și nici nu vor fi invocate metode de tip callback legate de conexiunea în cauză: <code javascript>​
 connection.destroy();​ connection.destroy();​
 +</​code>​
 +
 +În situația în care se dorește folosirea unui grup de conexiuni, se poate folosi metoda ''​createPool()''​ a obiectului ''​mysql''​ astfel încât numărul de conexiuni este specificat prin intermediul proprietății ''​connectionLimit''​. Obținerea unei conexiuni se face ulterior prin apelul metodei ''​getConnection()'',​ iar în momentul în care aceasta nu mai este necesară se poate apela metoda ''​release()''​. Un grup de conexiuni este terminat prin apelul metodei ''​end()''​.
 +
 +**Realizarea unei interogări** este realizată de regulă prin intermediul metodei ''​query()''​ apelată pe obiectul de tip ''​Connection'',​ care suportă următoarele forme:
 +  * ''​query(statement,​ callback)''​ - este utilizată de regulă pentru acele interogări care nu folosesc parametri sau pentru care parametrii sunt incluși în interogare; metoda primește ca argument o funcție de tip callback, având ca parametri obiectul eroare (în situația în care aceasta se produce), obiectul care reține rezultatul, acesta având forma unui tablou (chiar dacă rezultatul conține o singură înregistrare) și un obiect în care se regăsesc informații cu privire la câmpurile pentru care s-a realizat interogarea respectivă:​
 +
 +<code javascript>​
 +connection.query('​SELECT * FROM book', function(error,​ result, fields) {
 +  if (error) {
 +    console.log('​An error has occurred: %s', error);
 +    return;
 +  }
 +  for (var index = 0; index < result.length;​ index++) {
 +    var book = {
 +      "​title":​ result[index].title,​
 +      "​subtitle":​ result[index].subtitle,​
 +      "​description":​ result[index].description,​
 +      "​edition":​ result[index].edition,​
 +      "​printing_year":​ result[index].printing_year,​
 +      "​collection_id":​ result[index].collection_id
 +    };
 +    books.push(book);​
 +  }
 +});
 +</​code>​
 +
 +În situația în care sunt incluși parametri direct în interogare, se recomandă să se utilizeze metoda ''​escape()''​ a obiectului ''​connection'',​ ce transformă caracterele care ar putea să aibă un impact asupra interogării în codul corespunzător,​ care poate fi procesat de interpretorul SQL:
 +  * valorile numerice nu sunt modificate sub nici o formă;
 +  * obiectele ce rețin valori de adevăr sunt convertite la ''​true''​ / ''​false'';​
 +  * valorile de tip dată calendaristică sunt transformate în șiruri de caractere având formatul ''​YYYY-mm-dd HH:​ii:​ss'';​
 +  * obiectele care rețin informații binare (''​Buffer''​) sunt convertite la șiruri de caractere, reprezentate sub forma codului hexazecimal;​
 +  * pentru șirurile de caractere, sunt convertite caracterele speciale;
 +  * tablourile sunt convertite în șiruri de caractere având forma unei liste, în care delimitatorul este caracterul '','';​ în situația în care se folosesc tablouri imbricate, pe baza acestora se vor genera grupuri de liste, în care un grup este încadrat între caracterele ''​(''​ și ''​)'';​
 +  * obiectele sunt transformate în perechi de tip ''​atribut''​ = ''​valoare''​ pentru fiecare atribut (enumerabil) al acestuia (funcțiile fiind ignorate), valorile fiind determinate prin apelarea metodei ''​toString()'';​ valorile de tip ''​undefined''​ sau ''​null''​ sunt convertite automat la ''​NULL'';​ această funcționalitate poate fi utilizată pentru adăugarea unei valori într-o tabelă direct dintr-un obiect JavaScript, fără a se mai preciza coloanele care sunt folosite;
 +  * valorile de tip ''​Nan''​ / ''​Infinity''​ sunt lăsate ca atare, de vreme ce MySQL nu suportă astfel de valori, astfel că în acest caz va fi generată o eroare.
 +
 +<code javascript>​
 +connection.statement('​SELECT * FROM book b WHERE b.id = ' + connection.escape(bookId),​ function(error,​ result, fields) {
 +  // ...
 +});
 +</​code>​
 +
 +  * ''​query(statement,​ parameters, callback)'' ​ - este utilizată de regulă pentru acele interogări care folosesc parametri; faptul că se utilizează un parametru este marcat prin caracterul ''?'';​ argumentul care indică parametrii are forma unei liste și trebuie să respecte exact ordinea în care aceștia sunt menționați în cadrul interogării
 +
 +<code javascript>​
 +connection.query('​SELECT * FROM book b WHERE b.id = ?', [bookId], function(error,​ result, fields) {
 +  // ...
 +});
 +</​code>​
 +
 +  * ''​query(options,​ callback)''​ - este utilizat atunci când se dorește să se folosească anumite funcționalități pentru controlul modului în care vor fi furnizate rezultatele:​
 +    * ''​nestTables''​ permite stocarea valorilor corespunzătoare coloanelor având aceeași denumire în momentul în care sunt utilizate operații de asociere; se poate folosi valoarea ''​true''​ (situație în care denumirea coloanelor este prefixată de denumirea tabelei din care provin) sau ''​_''​ (caz în care valorile distincte aparținând unor coloane cu aceeași denumire sunt concatenate folosind acest delimitator); ​
 +    * ''​typeCast''​ stabilește dacă operația de conversie de la tipurile de date MySQL la tipurile de date JavaScript, realizată automat în mod implicit; este recomandat ca o astfel de facilitate să nu fie dezactivată;​
 +    * ''​timeout''​ indică perioada după care se va genera o eroare dacă nu se furnizează un rezultat în intervalul respectiv;
 +    * ''​sql''​ reprezintă interogarea care va fi executată;
 +    * ''​values''​ conține valorile parametrilor,​ sub forma unei liste, în situația în care interogarea este parametrizată.
 +
 +<code javascript>​
 +connection.query({
 +  sql: '​SELECT * FROM books WHERE b.id = ?',
 +  values: [bookId],
 +  nestTables: true,
 +  typeCast: false, // !!! NOT recommended
 +  timeout: 10000
 +}, function (error, result, fields) {
 +  // ... 
 +});
 +</​code>​
 +
 +  * ''​query(options,​ parameters, callback)''​ - este utilizat pentru interogări parametrizate,​ atunci când valorile acestora sunt furnizate distinct, nu în cadrul atributului ''​values'':​
 +
 +<code javascript>​
 +connection.query({
 +  sql: '​SELECT * FROM books WHERE b.id = ?',
 +  nestTables: true,
 +  typeCast: false, // !!! NOT recommended
 +  timeout: 10000
 +}, [bookId], function (error, result, fields) {
 +  // ... 
 +});
 +</​code>​
 +
 +În cazul interogărilor parametrizate,​ în situația în care pe post de parametrii se folosesc anumite câmpuri pentru care nu se aplică regulile de transformare obișnuite, se folosește șirul de caractere ''??''​. De asemenea, șirul de caractere poate fi pregătit local, înainte de a fi transmis către sistemul de gestiune pentru baze de date MySQL, prin intermediul metodei ''​format()'':​
 +
 +<code javascript>​
 +var unformatted_statement = '​SELECT * FROM ?? WHERE ?? = ?';
 +var parameters = ['​book',​ '​id',​ bookId];
 +var formatted_statement = mysql.format(unformatted_statement,​ parameters);​
 +// ...
 +</​code>​
 +
 +Pentru operațiile de **adăugare**,​ **modificare**,​ **ștergere**,​ se pot determina informații legate de identificatorul valorii care este adăugată, respectiv de numărul de înregistrări care au fost modificate / șterse, ca proprietăți ale obiectului ''​result''​ transmis ca parametru al funcției de tip callback în momentul în care este invocată metoda ''​query()'':​
 +  * ''​insertId''​ - stochează identificatorul înregistrării care a fost adăugată în baza de date în urma unei interogări de tip ''​INSERT''​ transmisă ca parametru al metodei ''​query()'':​ <code javascript>​
 +var book = {
 +  "​title":​ title,
 +  "​subtitle":​ subtitle,
 +  "​description":​ description,​
 +  "​edition":​ edition,
 +  "​printing_year":​ printing_year,​
 +  "​collection_id":​ collection_id
 +};
 +var query = connection.query('​INSERT INTO book SET ?', book, function(error,​ result) {
 +  if (error) {
 +    console.log('​An error has occurred: %s', error);
 +    return;
 +  }
 +  console.log('​The record has been successfully inserted with id %d', result.insertId);​
 +});
 +console.log(query.sql);​
 +</​code>​
 +  * ''​changedRows''​ - determină numărul de înregistrări care au fost modificate în urma unei interogări de tip ''​UPDATE''​ transmisă ca parametru al metodei ''​query()'':​ <code javascript>​
 +var query = connection.query('​UPDATE book SET edition = edition + 1 WHERE printing_year > ?', [printingYear],​ function(error,​ result) {
 +  if (error) {
 +    console.log('​An error has occurred: %s', error);
 +    return;
 +  }
 +  console.log('​%s records have been successfully updated',​ result.changedRows);​
 +});
 +</​code>​
 +  * ''​affectedRows''​ - determină numărul de înregistrări care au fost șterse în urma unei interogări de tip ''​DELETE''​ transmisă ca parametru al metodei ''​query()'':​ <code javascript>​
 +var query = connection.query('​DELETE FROM book WHERE collection_id IN ?', [collectionId],​ function(error,​ result) {
 +  if (error) {
 +    console.log('​An error has occurred: %s', error);
 +    return;
 +  }
 +  console.log('​%s records have been successfully deleted',​ result.affectedRows);​
 +});
 </​code>​ </​code>​
  
Line 1184: Line 1324:
   * în rădăcină:​   * în rădăcină:​
     * fișierul ''​main.js''​ - reprezintă codul sursă care va fi executat (folosind executabilul ''​node''​),​ aici fiind realizate diferite configurări,​ indicându-se rutele prin intermediul cărora vor fi procesate anumite pagini și lansându-se în execuție serverul http (pe un anumit port), pe baza căruia vor fi gestionate cererile și răspunsurile:​     * fișierul ''​main.js''​ - reprezintă codul sursă care va fi executat (folosind executabilul ''​node''​),​ aici fiind realizate diferite configurări,​ indicându-se rutele prin intermediul cărora vor fi procesate anumite pagini și lansându-se în execuție serverul http (pe un anumit port), pe baza căruia vor fi gestionate cererile și răspunsurile:​
-      * se indică faptul că aplicația va folosi framework-ul Express, precum și directorul în care se găsesc resursele care vor putea fi accesate (imagini, foi de stil, șabloane): <​code>​+      * se indică faptul că aplicația va folosi framework-ul Express, precum și directorul în care se găsesc resursele care vor putea fi accesate (imagini, foi de stil, șabloane): <​code ​javascript>
 var express = require('​express'​);​ var express = require('​express'​);​
 var app = express(); var app = express();
 app.use(express.static(path.join(__dirname,​ '​public'​)));​ app.use(express.static(path.join(__dirname,​ '​public'​)));​
 </​code>​ </​code>​
-      * se precizează care este directorul în care se găsesc paginile care vor fi vizualizate precum și motorul care va realiza această operație (în cazul de față, [[https://​www.npmjs.com/​package/​ejs|ejs (Embedded JavaScript Templates)]]):​ <​code>​+      * se precizează care este directorul în care se găsesc paginile care vor fi vizualizate precum și motorul care va realiza această operație (în cazul de față, [[https://​www.npmjs.com/​package/​ejs|ejs (Embedded JavaScript Templates)]]):​ <​code ​javascript>
 var path = require('​path'​);​ var path = require('​path'​);​
 app.set('​views',​ path.join(__dirname,​ '​views'​));​ app.set('​views',​ path.join(__dirname,​ '​views'​));​
Line 1195: Line 1335:
 </​code>​ </​code>​
       * se specifică faptul că aplicația va folosi modulele:       * se specifică faptul că aplicația va folosi modulele:
-        * ''​body-parser''​ pentru prelucrarea parametrilor dintr-o cerere / răspuns: <​code>​+        * ''​body-parser''​ pentru prelucrarea parametrilor dintr-o cerere / răspuns: <​code ​javascript>
 var bodyParser = require('​body-parser'​);​ var bodyParser = require('​body-parser'​);​
 app.use(bodyParser.urlencoded({ app.use(bodyParser.urlencoded({
Line 1201: Line 1341:
 })); }));
 </​code>​ </​code>​
-        * ''​serve-favicon''​ pentru folosirea unei pictograme pentru aplicația web: <​code>​+        * ''​serve-favicon''​ pentru folosirea unei pictograme pentru aplicația web: <​code ​javascript>
 var favicon = require('​serve-favicon'​);​ var favicon = require('​serve-favicon'​);​
 app.use(favicon(__dirname + '/​public/​images/​favicon.ico'​));​ app.use(favicon(__dirname + '/​public/​images/​favicon.ico'​));​
 </​code>​ </​code>​
-        * ''​express-session''​ pentru gestiunea sesiunilor - parametrii ''​saveUninitialized''​ și ''​resave''​ sunt folosiți pentru a indica transmiterea în cadrul sesiunii a variabilelor neinițializate și pentru persistența lor de-a lungul mai multor cicluri cerere ​ / răspuns:<​code>​+        * ''​express-session''​ pentru gestiunea sesiunilor - parametrii ''​saveUninitialized''​ și ''​resave''​ sunt folosiți pentru a indica transmiterea în cadrul sesiunii a variabilelor neinițializate și pentru persistența lor de-a lungul mai multor cicluri cerere ​ / răspuns:<​code ​javascript>
 var session = require('​express-session'​);​ var session = require('​express-session'​);​
 app.use(session({ app.use(session({
Line 1213: Line 1353:
 })); }));
 </​code>​ </​code>​
-        * ''​events''​ pentru folosirea de evenimente - se construiește un obiect de tip EventsEmitter prin intermediul căruia vor fi gestionate evenimentele (acesta va fi transmis ca parametru paginilor, pentru a se evita obținerea de noi instanțe în momentul în care pagina este încărcată din nou) <​code>​+        * ''​events''​ pentru folosirea de evenimente - se construiește un obiect de tip EventsEmitter prin intermediul căruia vor fi gestionate evenimentele (acesta va fi transmis ca parametru paginilor, pentru a se evita obținerea de noi instanțe în momentul în care pagina este încărcată din nou) <​code ​javascript>
 var events = require('​events'​);​ var events = require('​events'​);​
 var EventEmitter = new events.EventEmitter();​ var EventEmitter = new events.EventEmitter();​
 </​code>​ </​code>​
-      * se indică rutele (codul sursă) care va fi executat pentru fiecare pagină în parte, precum și parametrii care sunt transmiși acestora: <​code>​+      * se indică rutele (codul sursă) care va fi executat pentru fiecare pagină în parte, precum și parametrii care sunt transmiși acestora: <​code ​javascript>
 require('​./​routes/​login'​)(app,​ EventEmitter);​ require('​./​routes/​login'​)(app,​ EventEmitter);​
 require('​./​routes/​administrator'​)(app,​ EventEmitter);​ require('​./​routes/​administrator'​)(app,​ EventEmitter);​
 require('​./​routes/​client'​)(app,​ EventEmitter);​ require('​./​routes/​client'​)(app,​ EventEmitter);​
 </​code>​ </​code>​
-      * se lansează în execuție serverul HTTP pe un anumit port: <​code>​ +      * se lansează în execuție serverul HTTP pe un anumit port: <​code ​javascript> 
-app.lister(8080);+app.listen(8080);
 </​code>​ </​code>​
     * fișierul ''​package.json''​ - conține informații cu privire la aplicația web (denumire, versiune, cuvinte-cheie,​ autor precum și modulele folosite, descrise sub formă de dependențe - pentru fiecare atribut se indică denumirea și versiunea care se dorește a fi utilizată) <file json package.json>​     * fișierul ''​package.json''​ - conține informații cu privire la aplicația web (denumire, versiune, cuvinte-cheie,​ autor precum și modulele folosite, descrise sub formă de dependențe - pentru fiecare atribut se indică denumirea și versiunea care se dorește a fi utilizată) <file json package.json>​
Line 1246: Line 1386:
     * ''​css''​ - foi de stil;     * ''​css''​ - foi de stil;
     * ''​images''​ - imagini;     * ''​images''​ - imagini;
-  * directorul ''​routes''​ - conține codul sursă care va fi executat pentru fiecare pagină în parte; se indică care sunt contextele pe care le deservesc (parametrul metodei ''​app.route()''​) precum și metodele prin care pagina poate fi accesată (''​GET'',​ ''​POST'',​ ''​PUT'',​ ''​TRACE'',​ ''​OPTIONS'',​ ''​DELETE''​);​ metoda trebuie să fie făcută publică prin ''​module.exports''​ astfel încât să fie vizibilă la nivelul întregii aplicații web: <​code>​+  * directorul ''​routes''​ - conține codul sursă care va fi executat pentru fiecare pagină în parte; se indică care sunt contextele pe care le deservesc (parametrul metodei ''​app.route()''​) precum și metodele prin care pagina poate fi accesată (''​GET'',​ ''​POST'',​ ''​PUT'',​ ''​TRACE'',​ ''​OPTIONS'',​ ''​DELETE''​);​ metoda trebuie să fie făcută publică prin ''​module.exports''​ astfel încât să fie vizibilă la nivelul întregii aplicații web: <​code ​javascript>
 module.exports = function(app,​ EventEmitter) { module.exports = function(app,​ EventEmitter) {
   app.route('/'​)   app.route('/'​)
Line 1458: Line 1598:
 Iterația pe elementele unei liste se face folosind instrucțiunea ''​for'',​ prin intermediul unui contor care ia valori de la 0 la dimensiunea tabloului respectiv (''​languagesFilter.length''​). Iterația pe elementele unei liste se face folosind instrucțiunea ''​for'',​ prin intermediul unui contor care ia valori de la 0 la dimensiunea tabloului respectiv (''​languagesFilter.length''​).
  
-<​code>​+<​code ​javascript>
 <% for (var index = 0; index < languagesFilter.length;​ index++) { <% for (var index = 0; index < languagesFilter.length;​ index++) {
   // ...   // ...
Line 1471: Line 1611:
  
 În cazul butonului de tip ''​insert'',​ se poate verifica direct faptul că acesta este inclus în corpul cererii întrucât acesta este unic: În cazul butonului de tip ''​insert'',​ se poate verifica direct faptul că acesta este inclus în corpul cererii întrucât acesta este unic:
-<​code>​+<​code ​javascript>
 if (request.body['​insert_language.x'​]) { if (request.body['​insert_language.x'​]) {
   // ..   // ..
Line 1479: Line 1619:
 În cazul butonului de tip ''​delete'',​ se iterează asupra tuturor parametrilor incluși în corpul cererii, verificându-se dacă aceștia au formatul indicat, situație în care se parsează parametrul respectiv pentru a se determina denumirea limbii: În cazul butonului de tip ''​delete'',​ se iterează asupra tuturor parametrilor incluși în corpul cererii, verificându-se dacă aceștia au formatul indicat, situație în care se parsează parametrul respectiv pentru a se determina denumirea limbii:
  
-<​code>​+<​code ​javascript>
 var delete_language;​ var delete_language;​
 for (var parameter in request.body) { for (var parameter in request.body) {
Line 1490: Line 1630:
 Verificarea faptului că un element aparține unui tablou se face prin intermediul metodei [[http://​www.w3schools.com/​jsref/​jsref_indexof.asp|indexOf()]] prin care se determină poziția elementului în tablou, dacă este cazul. O valoare -1 indică faptul că elementul nu aparține tabloului. Verificarea faptului că un element aparține unui tablou se face prin intermediul metodei [[http://​www.w3schools.com/​jsref/​jsref_indexof.asp|indexOf()]] prin care se determină poziția elementului în tablou, dacă este cazul. O valoare -1 indică faptul că elementul nu aparține tabloului.
  
-<​code>​+<​code ​javascript>
 var position = languagesFilter.indexOf(language);​ var position = languagesFilter.indexOf(language);​
 if (position === -1) { if (position === -1) {
Line 1515: Line 1655:
 {{ :​laboratoare:​laborator04:​activitate_de_laborator_exercitiu08.png?​nolink&​700 }} {{ :​laboratoare:​laborator04:​activitate_de_laborator_exercitiu08.png?​nolink&​700 }}
  
-**a)** **butonul** are denumirea ''​insert_shoppingcart_{book_presentation_id}''​ unde ''​book_presentation_id''​ reprezintă identificatorul formatului de prezentare a cărții (de exemplu, ''​insert_shoppingcart_1''​ pentru formatul de identificare a cărții cu identificatorul 1); prin parsarea denumirii acestui parametru se obține identificatorul formatului de prezentare a cărții: <​code>​+**a)** **butonul** are denumirea ''​insert_shoppingcart_{book_presentation_id}''​ unde ''​book_presentation_id''​ reprezintă identificatorul formatului de prezentare a cărții (de exemplu, ''​insert_shoppingcart_1''​ pentru formatul de identificare a cărții cu identificatorul 1); prin parsarea denumirii acestui parametru se obține identificatorul formatului de prezentare a cărții: <​code ​javascript>
 if (parameter.startsWith('​insert_shoppingcart'​) && parameter.endsWith('​.x'​)) { if (parameter.startsWith('​insert_shoppingcart'​) && parameter.endsWith('​.x'​)) {
   bookPresentationId = parameter.substring(parameter.lastIndexOf('​_'​) + 1, parameter.indexOf('​.x'​));​   bookPresentationId = parameter.substring(parameter.lastIndexOf('​_'​) + 1, parameter.indexOf('​.x'​));​
Line 1521: Line 1661:
 </​code>​ </​code>​
 <note tip>​Pentru un element de tip ''<​input>''​ având atributul ''​type''​ cu valoarea ''​submit'',​ se transmit ca parametrii coordonatele la care se găsește mouse-ul în momentul în care se produce evenimentul de tip apăsare, acestea având aceeași denumire, sufixată de ''​.x'',​ respectiv ''​.y''​. Este important ca un singur parametru să fie procesat, în acest caz.</​note>​ <note tip>​Pentru un element de tip ''<​input>''​ având atributul ''​type''​ cu valoarea ''​submit'',​ se transmit ca parametrii coordonatele la care se găsește mouse-ul în momentul în care se produce evenimentul de tip apăsare, acestea având aceeași denumire, sufixată de ''​.x'',​ respectiv ''​.y''​. Este important ca un singur parametru să fie procesat, în acest caz.</​note>​
-**b)** **câmpul text** ce conține cantitatea corespunzătoare are denumirea ''​copies_shoppingcart_{book_presentation_id}''​ unde ''​book_presentation_id''​ reprezintă identificatorul formatului de prezentare a cărții (de exemplu, ''​copies_shoppingcart_1''​ pentru formatul de identificare a cărții cu identificatorul 1); valoarea corespunzătoare acestui parametru reprezintă cantitatea solicitată:​ <​code>​+**b)** **câmpul text** ce conține cantitatea corespunzătoare are denumirea ''​copies_shoppingcart_{book_presentation_id}''​ unde ''​book_presentation_id''​ reprezintă identificatorul formatului de prezentare a cărții (de exemplu, ''​copies_shoppingcart_1''​ pentru formatul de identificare a cărții cu identificatorul 1); valoarea corespunzătoare acestui parametru reprezintă cantitatea solicitată:​ <​code ​javascript>
 if (parameter.startsWith('​insert_shoppingcart'​) && parameter.endsWith('​.x'​)) { if (parameter.startsWith('​insert_shoppingcart'​) && parameter.endsWith('​.x'​)) {
   quantity = request.body['​copies_shoppingcart_'​ + bookPresentationId];​   quantity = request.body['​copies_shoppingcart_'​ + bookPresentationId];​
Line 1547: Line 1687:
   * o metodă de callback care primește ca rezultat o eroare (în situația în care aceasta se produce) respectiv rezultatul.   * o metodă de callback care primește ca rezultat o eroare (în situația în care aceasta se produce) respectiv rezultatul.
  
-<​code>​+<​code ​javascript>
 connection.query(statement,​ [parameters],​ function(error,​ result) { connection.query(statement,​ [parameters],​ function(error,​ result) {
   if (error) {   if (error) {
Line 1557: Line 1697:
  
 Interogarea care va fi folosită este: Interogarea care va fi folosită este:
-<​code>​+<​code ​mysql>
 SELECT bp.price AS price, b.title AS title, f.value AS value, l.name AS name SELECT bp.price AS price, b.title AS title, f.value AS value, l.name AS name
   FROM book_presentation bp, book b, format f, language ​   FROM book_presentation bp, book b, format f, language ​
Line 1565: Line 1705:
  
 Obiectul care va fi plasat în coșul de cumpărături are următoarea formă: Obiectul care va fi plasat în coșul de cumpărături are următoarea formă:
-<​code>​+<​code ​javascript>
 var record = { var record = {
   bookPresentationId:​ bookPresentationId,​   bookPresentationId:​ bookPresentationId,​
Line 1590: Line 1730:
   * în cazul în care lista este vidă, se afișează mesajul //The shopping cart is empty!//.   * în cazul în care lista este vidă, se afișează mesajul //The shopping cart is empty!//.
  
-<​code>​+<​code ​javascript>
 <% if (shoppingCart.length !== 0) { %> <% if (shoppingCart.length !== 0) { %>
   <!-- display the shopping cart -->   <!-- display the shopping cart -->
Line 1602: Line 1742:
 Se iterează asupra conținutului coșului de cumpărături (obiectul ''​shoppingCart''​),​ determinându-se,​ pentru fiecare element, cantitatea, prețul, titlul, valoarea, formatul de prezentare și limba. Este necesar să se calculeze și prețul total al coșului de cumpărături,​ într-o variabilă, prin însumarea tuturor valorilor corespunzătoare volumelor care se doresc a fi achiziționate. Se iterează asupra conținutului coșului de cumpărături (obiectul ''​shoppingCart''​),​ determinându-se,​ pentru fiecare element, cantitatea, prețul, titlul, valoarea, formatul de prezentare și limba. Este necesar să se calculeze și prețul total al coșului de cumpărături,​ într-o variabilă, prin însumarea tuturor valorilor corespunzătoare volumelor care se doresc a fi achiziționate.
  
-<​code>​+<​code ​javascript>
 <% for (var index = 0; index < shoppingCart.length;​ index++) { <% for (var index = 0; index < shoppingCart.length;​ index++) {
   var currentBookValue = shoppingCart[index].quantity * shoppingCart[index].price;​ %>   var currentBookValue = shoppingCart[index].quantity * shoppingCart[index].price;​ %>
Line 1631: Line 1771:
  
 <​spoiler|Indicații de Rezolvare>​ <​spoiler|Indicații de Rezolvare>​
-În cazul anulării unei comenzi, se şterge conţinutul obiectului ''​shoppingCart''​. <​code>​+În cazul anulării unei comenzi, se şterge conţinutul obiectului ''​shoppingCart''​. <​code ​javascript>
 if (request.body['​cancelcommand.x'​]) { if (request.body['​cancelcommand.x'​]) {
   shoppingCart = [];   shoppingCart = [];
Line 1643: Line 1783:
     * starea (câmpul ''​state''​) are valoarea ''​issued'';​     * starea (câmpul ''​state''​) are valoarea ''​issued'';​
     * identificatorul utilizatorului (câmpul ''​user_id''​) va fi preluat prin intermediul sesiunii ''​request.session.user_id'';​     * identificatorul utilizatorului (câmpul ''​user_id''​) va fi preluat prin intermediul sesiunii ''​request.session.user_id'';​
-<​code>​+<​code ​javascript>
 var query_insert_invoice_header = '​INSERT INTO invoice_header (identification_number,​ issue_date, state, user_id) VALUES (' var query_insert_invoice_header = '​INSERT INTO invoice_header (identification_number,​ issue_date, state, user_id) VALUES ('
     + '​\''​ + generateIdentificationNumber(3,​ 6) + '​\',​ CURRENT_DATE(),​ \'​issued\',​ \''​ + request.session.user_id + '​\'​)';​     + '​\''​ + generateIdentificationNumber(3,​ 6) + '​\',​ CURRENT_DATE(),​ \'​issued\',​ \''​ + request.session.user_id + '​\'​)';​
Line 1655: Line 1795:
     * altfel, se adaugă un mesaj de eroare care va fi afișat în cadrul paginii (transmis prin intermediul parametrului ''​errorMessage''​);​     * altfel, se adaugă un mesaj de eroare care va fi afișat în cadrul paginii (transmis prin intermediul parametrului ''​errorMessage''​);​
   * se goleşte coşul de cumpărături.   * se goleşte coşul de cumpărături.
-<​code>​+<​code ​javascript>
 var currentBookPresentationId = shoppingCart[index].bookPresentationId;​ var currentBookPresentationId = shoppingCart[index].bookPresentationId;​
 var currentQuantity = shoppingCart[index].quantity;​ var currentQuantity = shoppingCart[index].quantity;​
Line 1664: Line 1804:
 <note warning> <note warning>
 Întrucât este important ca operațiile să fie realizate sincron, un pas al iterației va fi tratat de o metodă de callback a unui eveniment, parametrizată cu o variabilă care reține pasul iterației respective. Se lansează un eveniment cu pasul 0, acesta fiind incrementat după ce au fost completate procesările aferente și relansat. Când s-a parcurs întreaga listă, se lansează un alt eveniment pe care este golit coșul de cumpărături (dacă această operație nu ar fi fost realizată sincron, s-ar fi riscat ca ea să fie executată înainte de terminarea iterației pe întreg coșul de cumpărături) și se marchează terminarea tuturor operațiilor (variabila ''​commandProcessing''​ va avea valoarea ''​true''​ și se apelează metoda ''​renderClient()''​ pentru a se afișa pagina, în cazul în care toate celelalte procesări au fost încheiate). Întrucât este important ca operațiile să fie realizate sincron, un pas al iterației va fi tratat de o metodă de callback a unui eveniment, parametrizată cu o variabilă care reține pasul iterației respective. Se lansează un eveniment cu pasul 0, acesta fiind incrementat după ce au fost completate procesările aferente și relansat. Când s-a parcurs întreaga listă, se lansează un alt eveniment pe care este golit coșul de cumpărături (dacă această operație nu ar fi fost realizată sincron, s-ar fi riscat ca ea să fie executată înainte de terminarea iterației pe întreg coșul de cumpărături) și se marchează terminarea tuturor operațiilor (variabila ''​commandProcessing''​ va avea valoarea ''​true''​ și se apelează metoda ''​renderClient()''​ pentru a se afișa pagina, în cazul în care toate celelalte procesări au fost încheiate).
-<​code>​+<​code ​javascript>
 var shoppingCartEvent = function(index) { var shoppingCartEvent = function(index) {
   if (index >= shoppingCart.length) {   if (index >= shoppingCart.length) {
Line 1693: Line 1833:
  
 În fișierul ''​client.js'',​ în cazul în care a fost apăsat butonul pentru operația de deautentificare (corpul cererii conține parametrul ''​signout.x'':​ ''​if (request.body['​signout.x'​])''​):​ În fișierul ''​client.js'',​ în cazul în care a fost apăsat butonul pentru operația de deautentificare (corpul cererii conține parametrul ''​signout.x'':​ ''​if (request.body['​signout.x'​])''​):​
-  * se distruge sesiunea, folosind metoda ''​destroy''​ ce primește ca parametru o metodă de callback prin intermediul căreia se transmite dacă s-a produs o eroare: <​code>​+  * se distruge sesiunea, folosind metoda ''​destroy''​ ce primește ca parametru o metodă de callback prin intermediul căreia se transmite dacă s-a produs o eroare: <​code ​javascript>
 request.session.destroy(function (error) { request.session.destroy(function (error) {
   if (error) {   if (error) {
Line 1700: Line 1840:
 }); });
 </​code>​ </​code>​
-  * se transferă contextul către pagina ''​login'',​ având parametrul ''​error''​ cu valoarea șirul vid: <​code ​java>+  * se transferă contextul către pagina ''​login'',​ având parametrul ''​error''​ cu valoarea șirul vid: <​code ​ ​javascript>
 response.render('​login',​ { response.render('​login',​ {
   error: ''​   error: ''​
laboratoare/laborator06.1448842551.txt.gz · Last modified: 2015/11/30 02:15 by Andrei Roșu-Cojocaru
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0