Table of Contents

FLOW-EXP-001 — Registrazione di un job di export nello spooler — ExportService

Flusso end-to-end di registrazione/avvio di un job di export asincrono del dominio ExportService. L'operazione rappresentativa di scrittura autonoma è la registrazione del job nello spooler: il client (WCF ApplicationService.svc) chiama, tramite .NET Remoting, il servizio Windows ExportService, che invoca la stored procedure Oracle RPS_SETSPOOLER_LASTQUERY. Questa esegue un MERGE (INSERT/UPDATE) sulla tabella GLOBAL_SPOOLER (INFOCAD_TEST38), creando la riga di spooler in stato in coda (STATUS = 0) con nome export, SQL di estrazione e scadenza. Nessun ORM. Il job di export vero e proprio ne aggiorna poi lo stato (RPS_SETSPOOLER_STATUS) durante il ciclo di vita.

  • Flow ID: FLOW-EXP-001
  • Repository: InfocadServer (ExportService / ExportServiceControllers / ExportServiceInterface, C#; DocumentDAL, VB.NET) + InfocadWeb (WCF ApplicationService.svc, C#)
  • Confidence complessiva: VERIFIED (catena WCF → controller Remoting → servizio → DAL Execute*StoredProcedure → stored procedure, confermata su codice E su sorgente DB USER_SOURCE; mappa su GLOBAL_SPOOLER confermata su USER_TAB_COLUMNS/USER_DEPENDENCIES)
  • has_standalone_write: true — la registrazione dello spooler (RPS_SETSPOOLER_LASTQUERY → INSERT/UPDATE GLOBAL_SPOOLER) è una scrittura autonoma del dominio; l'aggiornamento di stato (RPS_SETSPOOLER_STATUS) è la seconda scrittura del ciclo di vita.

Obiettivo di business

Consentire a un utente autenticato di richiedere l'esportazione asincrona di un insieme di dati (griglia DataView, immagini, documenti/PDF) senza bloccare la sessione web. La richiesta viene materializzata come "job" persistente in una coda (spooler): al termine l'utente troverà nella propria area un file scaricabile. La registrazione crea/aggiorna la riga di spooler dell'utente in stato in coda, memorizzando nome dell'export, query SQL di estrazione, chiavi e conteggio righe.

Attori

  • Utente autenticato (operatore su un DataView/griglia, area documenti, ecc.) — path interattivo web.
  • Client WCF ApplicationService.svc (WebMachine CASSANDRA / IEM) — orchestratore lato web che registra il job e poi ne avvia l'esecuzione.
  • Servizio Windows ExportService (host Remoting registrato in Business/Start.vb) — esegue la scrittura DB e ospita i job di export (DataViewExportReader, ImagesExportReader, DocumentsPDFJob…).
  • Oracle INFOCAD_TEST38 — hub anagrafico: tabella GLOBAL_SPOOLER (coda job) e procedure RPS_*; risoluzione utente/tenant cross-schema su ASPNET_TEST38.ORA_ASPNET_USERS/APPLICATIONS.

Trigger

Chiamata WCF a un metodo di export di ApplicationService.svc, es. ExportImagesData (ApplicationService.svc.cs:170) o ExportDocumentsData (:184), che per prima cosa registra il job via ExportServiceController.SetSpooler_LastQuery(...) (ApplicationService.svc.cs:175,189,203). Per l'export della griglia DataView la registrazione avviene a monte (impostazione dell'ultima query), poi ExportData (:148) avvia soltanto l'esecuzione leggendo la riga di spooler già in stato 0.

Frontend entry point

  • Servizio WCF: InfocadWeb/WebMachine/CASSANDRA/WebServices/ApplicationService.svc.cs (contratto IApplicationService), metodi ExportData (:148), ExportDocument (:156), ExportImagesData (:170), ExportDocumentsData (:184), ExportDocumentsDataZip (:198).
  • Gate di accesso: ValidateToken(token: request.UserName) all'ingresso di ogni metodo (ApplicationService.svc.cs:150,158,172,186,200) — risolve/valida l'utente dal token.

Sequenza principale (main sequence)

  1. Il client web invoca ApplicationService.ExportImagesData(request) (:170); ValidateToken valida l'utente (:172).
  2. Il metodo istanzia ExportServiceController e DataViewExportController (:173-174) e registra il job: ctrl.SetSpooler_LastQuery(request.UserName, request.Procedure, string.Empty) (:175).
  3. ExportServiceController.SetSpooler_LastQuery (ExportServiceController.cs:53) inoltra via .NET Remoting al servizio ExportService (proxy creato nel costruttore, canale …/ExportService.rem, ExportServiceController.cs:17).
  4. ExportService.SetSpooler_LastQuery (ExportService.cs:298) prepara i parametri Oracle (PUSERNAME, PNAME, PSQL) e chiama dl.ExecuteNonQueryStoredProcedure("RPS_SETSPOOLER_LASTQUERY") (ExportService.cs:312).
  5. Oracle RPS_SETSPOOLER_LASTQUERY (INFOCAD_TEST38):
    • risolve USERID (RAW) dell'utente da ASPNET_TEST38.ORA_ASPNET_USERS/APPLICATIONS filtrando per LOWER(USER) (schema applicativo) e LOWEREDUSERNAME (src:17-23);
    • se PKEYS valorizzato, calcola il conteggio righe con EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM (…)' (src:12-15);
    • esegue un MERGE INTO GLOBAL_SPOOLER con chiave (USERID, STATUS = 0) (src:25-34):
      • WHEN NOT MATCHED → INSERT (USERID, EXPORTNAME, STATUS=0, EXPORTDATA=PSQL, STARTDATE=SYSDATE, EXPIREDATE=SYSDATE+1, EXPORTKEYS, EXPORTTOTAL) (src:29-32) — nuova riga di spooler in coda;
      • WHEN MATCHED → UPDATE dei campi export sulla riga in coda esistente (src:33-34).
  6. Registrato il job, il metodo WCF ne avvia l'esecuzione: dv_ctrl.StartExport(request.UserName, ExportType.IMAGES, …) (ApplicationService.svc.cs:177).
  7. DataViewService.PrepareExcelJobForExecution/PrepareJobForExecution legge la riga appena creata con RPS_GETSPOOLER_INFO (DataViewService.cs:37,110): con PIDSPOOLER NULL la SP restituisce la riga dell'utente in STATUS = 0 (RPS_GETSPOOLER_INFO src:24-30), da cui si ricava ID_SPOOLER.
  8. Il reader parte (export.Start(), DataViewService.cs:85,147) e, in BaseGetData, marca il job in esecuzione: _ctrl.SetSpooler_Status(idspooler, 1, "")RPS_SETSPOOLER_STATUS (DataViewExportReader.cs:48; ExportService.cs:344,358). _ctrl è un'istanza in-process di ExportService (DataViewDataReaderJob.cs:45).
  9. Al completamento: _ctrl.SetSpooler_Progress(idspooler, 100) (DataViewDataReaderJob.cs:192) e _ctrl.SetSpooler_Status(idspooler, 2, fileName) (DataViewDataReaderJob.cs:206) → il job è completato con il nome file prodotto.
  10. Oracle RPS_SETSPOOLER_STATUS: UPDATE GLOBAL_SPOOLER SET STATUS = :PSTATUS, FILENAME = COALESCE(:PFILENAME, FILENAME) WHERE ID_SPOOLER = :PIDSPOOLER (src:7-9).
  11. L'utente scarica poi il file (ExportService.ExportFileBytes, ExportService.cs:70) e/o consulta lo stato spooler; i job scaduti vengono ripuliti da CleanExport (ExportService.cs:32).

API / service

  • Ingresso web (SOAP/WCF): ApplicationService.svc — metodi ExportData/ExportDocument/ ExportImagesData/ExportDocumentsData/ExportDocumentsDataZip.
  • Servizio applicativo (Remoting, SingleCall): ExportService, DataViewService, DocumentService, MaintenanceService, registrati in Business/Start.vb:999+ (es. DataViewExportService.rem, ExportService.rem).
  • Controller proxy (client Remoting): ExportServiceController, DataViewExportController, DocumentExportController, MaintenanceExportController (ExportServiceControllers/).

Backend

  • Orchestratore web: ApplicationService.svc.cs (C#).
  • Interfaccia servizio: Descor.ExportServiceInterface.IExportService / IDataViewService (ExportServiceInterface/).
  • Controller (proxy Remoting): Descor.ExportServiceControllers.ExportServiceController (ExportServiceControllers/ExportServiceController.cs), costruito con Activator.GetObject(typeof(IExportService), CHANNEL + "://" + SERVERADDRESS + "/ExportService.rem").
  • Servizio (DAO): Descor.ExportService.ExportService : MarshalByRefObject, IExportService (ExportService/ExportService.cs) e sottoclasse DataViewService (ExportService/DataViewService.cs).
  • Job: DataViewDataReaderJob/DataViewExportReader (Excel), ImagesExportReader, DocumentsPDFJob/DocumentsZipJob (ExportService/Deployment/**).
  • Pattern DAL: new DataLayer(Properties.Settings.Default.ConnectionName)dl.Parameters.Add(new OracleParameter(...))dl.ExecuteNonQueryStoredProcedure("RPS_…") (ODP.NET, Oracle.DataAccess.Client). Nessun ORM.

Query / stored procedure

Passo Stored procedure (Oracle) Chiamata da (DAL)
Registrazione job (INSERT/UPDATE GLOBAL_SPOOLER) INFOCAD_TEST38.RPS_SETSPOOLER_LASTQUERY (MERGE) ExportService.cs:312
Lettura riga spooler (get ID_SPOOLER) INFOCAD_TEST38.RPS_GETSPOOLER_INFO DataViewService.cs:37,110
Estrazione dati da esportare (READ) INFOCAD_TEST38.RPS_GETSPOOLER_QUERY DataViewExportReader.cs:78
Aggiornamento stato job (UPDATE GLOBAL_SPOOLER) INFOCAD_TEST38.RPS_SETSPOOLER_STATUS ExportService.cs:358
Aggiornamento avanzamento (UPDATE GLOBAL_SPOOLER) INFOCAD_TEST38.RPS_SETSPOOLER_PROGRESS ExportService.cs:402
Cancellazione job per id (DELETE GLOBAL_SPOOLER) INFOCAD_TEST38.RPS_DELETESPOOLER_BYID ExportService.cs:61,440
Registrazione job documenti (temp + MERGE) INFOCAD_TEST38.DOC_INSERTSPOOLER_QUERYRPS_SETSPOOLER_LASTQUERY Document_DAL.vb:3368

Tabelle lette (read)

  • INFOCAD_TEST38: GLOBAL_SPOOLER (lettura riga in coda / per id in RPS_GETSPOOLER_INFO).
  • ASPNET_TEST38: ORA_ASPNET_USERS, ORA_ASPNET_APPLICATIONS (risoluzione USERID dell'utente — da USER_DEPENDENCIES di RPS_SETSPOOLER_LASTQUERY/RPS_GETSPOOLER_INFO).
  • Percorso documenti: DOCS_DOCUMENT_EXPORT, DOCS_IDDOCUMENT_TEMP_EXPORT (SELECT di export dentro DOC_INSERTSPOOLER_QUERY src:25-48).

Tabelle modificate (write)

  • INFOCAD_TEST38: GLOBAL_SPOOLER (RW — coda dei job di export):
    • INSERT/UPDATE via MERGE in RPS_SETSPOOLER_LASTQUERY (registrazione job, STATUS = 0; colonne USERID, EXPORTNAME, STATUS, EXPORTDATA, STARTDATE, EXPIREDATE, EXPORTKEYS, EXPORTTOTAL);
    • UPDATE STATUS/FILENAME via RPS_SETSPOOLER_STATUS (ciclo di vita: 1 = in esecuzione, 2 = completato);
    • UPDATE EXPORTPROGRESS via RPS_SETSPOOLER_PROGRESS;
    • DELETE via RPS_DELETESPOOLER_BYID (cleanup / rimozione job).
  • DOCS_IDDOCUMENT_TEMP_EXPORT (RW — path documenti): DELETE per utente + INSERT id documenti in DOC_INSERTSPOOLER_QUERY (src:12-13,20-21), poi registrazione job via RPS_SETSPOOLER_LASTQUERY.
  • Nota: GLOBAL_SPOOLER ha anche un TRIGGER (USER_OBJECTS → TABLE + TRIGGER): l'ID_SPOOLER è verosimilmente assegnato da sequenza/trigger (non presente nel corpo RPS_SETSPOOLER_LASTQUERY; vedi Open questions).

Validazione

  • Lato WCF: ValidateToken(token: request.UserName) all'ingresso di ogni metodo di export (ApplicationService.svc.cs:150,158,172,186,200) — l'UserName usato a valle è quello risolto dal token.
  • Lato DB: RPS_SETSPOOLER_LASTQUERY risolve USERID con una SELECT … INTO (src:17-23); se l'utente non esiste solleva NO_DATA_FOUND (nessuna riga scritta). RPS_GETSPOOLER_INFO gestisce esplicitamente NO_DATA_FOUND restituendo un cursore con -100 (src:34-36).
  • Idempotenza registrazione: la chiave del MERGE (USERID, STATUS = 0) garantisce una sola riga in coda per utente: una nuova richiesta aggiorna la riga pendente invece di duplicarla.

Side effects

  • Creazione/aggiornamento della riga di spooler dell'utente (stato 0) con EXPIREDATE = SYSDATE + 1 (scadenza a 24h → candidata a CleanExport/RPS_GETEXPIREDSPOOLERS + RPS_DELETESPOOLER_BYID).
  • Al completamento del job: file fisico prodotto in _ctx.UserPath (Excel/ZIP/PDF) e FILENAME registrato in GLOBAL_SPOOLER (RPS_SETSPOOLER_STATUS, PSTATUS = 2).
  • Path documenti: svuotamento+ripopolamento di DOCS_IDDOCUMENT_TEMP_EXPORT per l'utente.
  • Alla cancellazione (DeleteSpooler_ByID): eliminazione del file su disco prima del DELETE della riga (ExportService.cs:412-440).

Percorsi alternativi / di errore

  • Export griglia DataView (Excel): ApplicationService.ExportData (:148) → DataViewExportController.StartExcelExport(user, fields, null) (:152) — la riga di spooler è già in stato 0 (registrata a monte); il job la legge via RPS_GETSPOOLER_INFO e la porta a 12.
  • Export documenti (Excel): ExportDocument (:156) → DocumentController.InsertSpoolerExportData (:161) → Document_DAL.InsertSpoolerExportDataDOC_INSERTSPOOLER_QUERY (che popola la temp e chiama RPS_SETSPOOLER_LASTQUERY con la SELECT di export, src:50) → StartExcelExportForDocument (:165).
  • Export PDF/ZIP documenti: ExportDocumentsData/ExportDocumentsDataZip (:184,198) → SetSpooler_LastQuery + DocumentExportController.StartExport/StartExportZip.
  • Errore utente inesistente: SELECT … INTO USERID in RPS_SETSPOOLER_LASTQUERYNO_DATA_FOUND non gestito ⇒ eccezione propagata; SetSpooler_LastQuery restituisce false/exception loggata (ExportService.cs:314-318) e il metodo WCF ritorna -1 (ApplicationService.svc.cs:179).
  • Cleanup job scaduti: CleanExport (ExportService.cs:32) → RPS_GETEXPIREDSPOOLERS + RPS_DELETESPOOLER_BYID (:41,61).

Diagramma di sequenza

sequenceDiagram
    actor U as Utente
    participant WCF as ApplicationService.svc (ExportImagesData)
    participant CTRL as ExportServiceController (Remoting proxy)
    participant SVC as ExportService (servizio Windows)
    participant DV as DataViewService / DataViewExportReader
    participant DB as Oracle INFOCAD_TEST38 (GLOBAL_SPOOLER)

    U->>WCF: richiesta export (request)
    WCF->>WCF: ValidateToken(request.UserName)
    WCF->>CTRL: SetSpooler_LastQuery(user, name, sql)
    CTRL->>SVC: (Remoting) SetSpooler_LastQuery(...)
    SVC->>DB: RPS_SETSPOOLER_LASTQUERY (PUSERNAME, PNAME, PSQL)
    alt nessuna riga in coda (STATUS=0)
        DB->>DB: MERGE -> INSERT GLOBAL_SPOOLER (STATUS=0)
    else riga in coda esistente
        DB->>DB: MERGE -> UPDATE GLOBAL_SPOOLER (EXPORTNAME/EXPORTDATA...)
    end
    DB-->>SVC: OK
    WCF->>CTRL: StartExport / StartExcelExport(user, ...)
    CTRL->>DV: (Remoting) StartExport(...)
    DV->>DB: RPS_GETSPOOLER_INFO -> ID_SPOOLER (STATUS=0)
    DV->>DB: RPS_SETSPOOLER_STATUS(id, 1, '')  (in esecuzione)
    DV->>DB: RPS_GETSPOOLER_QUERY (estrazione dati)
    DV->>DV: genera file (xlsx/zip/pdf) in UserPath
    DV->>DB: RPS_SETSPOOLER_STATUS(id, 2, fileName)  (completato)
    DB-->>DV: OK
    WCF-->>U: ID_SPOOLER (o -1 su errore)

Matrice di tracciabilità

Layer Artefatto Evidenza (file:riga)
UI/Web (WCF) ApplicationService.ExportImagesDataSetSpooler_LastQuery + StartExport ApplicationService.svc.cs:170,175,177
UI/Web (WCF) ExportData / ExportDocument / ExportDocumentsData(Zip) ApplicationService.svc.cs:148,156,184,198
Controller (proxy) ExportServiceController.SetSpooler_LastQuery (ctor Remoting) ExportServiceController.cs:17,53,55
Interfaccia IExportService.SetSpooler_LastQuery / SetSpooler_Status IExportService.cs:24,28
Servizio (DAO) ExportService.SetSpooler_LastQueryRPS_SETSPOOLER_LASTQUERY ExportService.cs:298,312
Servizio (DAO) ExportService.SetSpooler_StatusRPS_SETSPOOLER_STATUS ExportService.cs:344,358
Servizio (DAO) SetSpooler_Progress / DeleteSpooler_ByID / CleanExport ExportService.cs:390,402,412,440,32,61
Job DataViewService.PrepareExcelJobForExecutionRPS_GETSPOOLER_INFO; StartExcelExport DataViewService.cs:17,37,78,85
Job DataViewExportReader.BaseGetDataSetSpooler_Status(id,1,'') + RPS_GETSPOOLER_QUERY DataViewExportReader.cs:48,78
Job DataViewDataReaderJob: new ExportService(); SetSpooler_Progress(100); SetSpooler_Status(id,2,file) DataViewDataReaderJob.cs:45,192,206
Registrazione Remoting RegisterWellKnownServiceType(DataViewService, "DataViewExportService.rem") Business/Start.vb:999
Path documenti Document_DAL.InsertSpoolerExportDataDOC_INSERTSPOOLER_QUERY Document_DAL.vb:3358,3368
DB RPS_SETSPOOLER_LASTQUERY (MERGE su GLOBAL_SPOOLER) USER_SOURCE RPS_SETSPOOLER_LASTQUERY src:17-23,25-34
DB RPS_SETSPOOLER_STATUS (UPDATE GLOBAL_SPOOLER) USER_SOURCE src:7-9
DB RPS_GETSPOOLER_INFO (SELECT GLOBAL_SPOOLER) USER_SOURCE src:8-32
DB DOC_INSERTSPOOLER_QUERY (temp + call RPS_SETSPOOLER_LASTQUERY) USER_SOURCE src:12-13,20-21,50
DB (schema) GLOBAL_SPOOLER colonne ID_SPOOLER(NUMBER), USERID(RAW), EXPORTNAME, STATUS, EXPORTDATA(CLOB), FILENAME, EXPIREDATE, EXPORTPROGRESS, EXPORTTOTAL USER_TAB_COLUMNS

Reverse trace (dal DB/servizio ai chiamanti)

  • RPS_SETSPOOLER_LASTQUERY (dipendenze USER_DEPENDENCIES: GLOBAL_SPOOLER, ASPNET_TEST38.ORA_ASPNET_USERS/APPLICATIONS, HELPERS, MYINTTABLE) è la procedura di registrazione job. È raggiunta da: (a) ExportService.SetSpooler_LastQuery (ExportService.cs:312), a sua volta invocata da ApplicationService.ExportImagesData/ExportDocumentsData/ExportDocumentsDataZip (ApplicationService.svc.cs:175,189,203); (b) internamente da DOC_INSERTSPOOLER_QUERY src:50 (path documenti Excel, via Document_DAL.InsertSpoolerExportData).
  • RPS_SETSPOOLER_STATUS (dipende solo da GLOBAL_SPOOLER) è invocata da ExportService.SetSpooler_Status (ExportService.cs:358), chiamata da tutti i reader/job di export all'avvio (…, 1, "") e al termine (…, 2, fileName): DataView (DataViewExportReader.cs:48, DataViewDataReaderJob.cs:206), Immagini (ImagesDataReaderJob.cs:225), Maintenance (MaintenanceDataReaderJob.cs:158), Documenti (DocumentsPDFJob.cs:190, DocumentsZipJob.cs:238).
  • Forward e reverse concordano: il metodo WCF di export registra il job con RPS_SETSPOOLER_LASTQUERY (INSERT GLOBAL_SPOOLER, STATUS=0) e i job aggiornano la stessa riga con RPS_SETSPOOLER_STATUSNO CONFLICTING.
  • Modello a spooler asincrono: ogni export è persistito come riga di GLOBAL_SPOOLER con macchina a stati STATUS: 0 in coda → 1 in esecuzione → 2 completato (RPS_SETSPOOLER_STATUS src:7-9; costanti nei reader).
  • Una sola richiesta pendente per utente: chiave MERGE (USERID, STATUS=0) (src:25-28).
  • Scadenza a 24h: EXPIREDATE = SYSDATE + 1 (src:32), abbinata al cleanup RPS_GETEXPIREDSPOOLERS
    • RPS_DELETESPOOLER_BYID.
  • Multi-tenant/identità: USERID risolto da ASPNET_TEST38 filtrando anche per LOWER(USER) (schema applicativo corrente) → isolamento per applicazione/tenant (src:22).
  • .NET Remoting SingleCall come trasporto client→servizio (non WCF): Business/Start.vb:999+.

Evidenza (file:line)

Punti chiave (codice): ApplicationService.svc.cs:148,150,156,158,161,165,170,172,173,174,175,177,184,186,189,191,198,200,203; ExportServiceController.cs:17,53,55; IExportService.cs:24,28; ExportService.cs:32,41,61,70,298,312,344,358,390,402,412,440; DataViewService.cs:17,34,37,78,85,92,107,110,134,147; DataViewExportReader.cs:48,78; DataViewDataReaderJob.cs:31,45,192,206; Business/Start.vb:999; Document_DAL.vb:3358,3368.

Punti chiave (DB, INFOCAD_TEST38, letti in sola lettura via USER_SOURCE/USER_DEPENDENCIES/USER_TAB_COLUMNS/USER_OBJECTS): RPS_SETSPOOLER_LASTQUERY firma src:1-5; risoluzione USERID src:17-23; conteggio chiavi src:12-15; MERGE su GLOBAL_SPOOLER INSERT/UPDATE src:25-34. RPS_SETSPOOLER_STATUS UPDATE GLOBAL_SPOOLER src:7-9. RPS_GETSPOOLER_INFO SELECT (per id / per utente+STATUS=0) src:8-32, NO_DATA_FOUND src:34-36. DOC_INSERTSPOOLER_QUERY DELETE/INSERT temp src:12-13,20-21, call RPS_SETSPOOLER_LASTQUERY src:50. GLOBAL_SPOOLER è TABLE (+ TRIGGER) con colonne ID_SPOOLER NUMBER (NOT NULL), USERID RAW, EXPORTNAME/FILENAME VARCHAR2, STATUS/EXPORTPROGRESS/EXPORTTOTAL/ISPUBLIC NUMBER, EXPORTDATA/EXPORTKEYS CLOB, STARTDATE/EXPIREDATE DATE (USER_TAB_COLUMNS). Dipendenze RPS_SETSPOOLER_LASTQUERYGLOBAL_SPOOLER, ASPNET_TEST38.ORA_ASPNET_USERS/APPLICATIONS, HELPERS (PACKAGE), MYINTTABLE (TYPE) (USER_DEPENDENCIES).

Confidence

VERIFIED. La catena WCF → controller (Remoting) → servizio ExportService → DAL ExecuteNonQueryStoredProcedureRPS_SETSPOOLER_LASTQUERY è confermata sul codice; l'effetto di scrittura (INSERT/UPDATE su GLOBAL_SPOOLER) e l'aggiornamento di stato (RPS_SETSPOOLER_STATUS) sono confermati sul sorgente Oracle (USER_SOURCE) e sul catalogo (USER_TAB_COLUMNS, USER_DEPENDENCIES, USER_OBJECTS). ≥2 tipi di evidenza (codice C#/VB.NET + sorgente/catalogo DB).

Open questions

  • Assegnazione di ID_SPOOLER: GLOBAL_SPOOLER ha un TRIGGER (da USER_OBJECTS) verosimilmente incaricato di popolare ID_SPOOLER da sequenza sull'INSERT; il corpo del trigger non è stato ispezionato.
  • Dove viene registrata la query SQL reale per l'export della griglia DataView (nei metodi WCF ExportImagesData/ExportDocumentsData il parametro PSQL è string.Empty): esiste con ogni probabilità un'impostazione a monte dell'"ultima query" del DataView che valorizza EXPORTDATA; non individuato il chiamante che passa il SQL non vuoto (fuori dominio ExportService).
  • Semantica esatta dei valori STATUS oltre a 0/1/2 (es. eventuali stati di errore) non normata nel codice ispezionato.
  • RPS_GETSPOOLER_QUERY (estrazione dati da esportare) non ispezionata in dettaglio sul sorgente DB (letta solo come READ nel reader).