Willino Blog
mercoledì 25 novembre 2009
Chiusa Sclafani,la preside non espone il crocifisso il sindaco è pronto a multarla
Palermo - Cinquecento euro di multa perché manca il crocifisso nel suo ufficio. E´ quello che rischia la preside dell´istituto comprensivo Reina di Chiusa Sclafani, dopo il blitz della polizia municipale di ieri mattina. Tutto inizia venerdì scorso, quando il sindaco del paese Francesco Di Giorgio (Pdl) fa notificare alla preside dell´istituto, Francesca Accardo, un insolito provvedimento in netta contrapposizione con la recente sentenza della Corte suprema di Strasburgo.
Il sindaco ordina di «mantenere il crocifisso nelle aule scolastiche e negli uffici pubblici del comune di Chiusa Sclafani, come espressione dei fondamentali valori civili e culturali dello Stato italiano». «Il personale della polizia municipale - continua l´ordinanza - controllerà entro 15 giorni l´osservanza dell´ordinanza» e «ai trasgressori sarà applicata la sanzione di 500 euro».
Ieri mattina, parecchi giorni prima dei 15 ipotizzati nel provvedimento, al portone della scuola si presentano due vigili urbani. «Avrei anche potuto non farli entrare - dichiara la preside - ma come rappresentante delle istituzioni ho pensato che non fosse corretto». I due hanno fatto un rapido sopralluogo in tutte le classi e negli uffici amministrativi trovando il crocifisso al proprio posto.
«Ma quando sono entrati nella mia stanza mi hanno fatto notare che il crocifisso mancava», spiega la Accardo, che non riesce a darsi pace per «l´assurda ordinanza» e la celerità della visita. «Non riesco a spiegarmi - continua - i motivi del provvedimento e penso che adesso possano anche farmi la multa: nessuno ha toccato i crocifissi nelle aule e nelle altre stanze e, francamente, non mi ero neppure accorta che nel mio ufficio mancava».
Il capo d´istituto è letteralmente furibonda mentre racconta una storia che ha del surreale. «Penso di vivere in un paese democratico, non in una dittatura: vorrei continuare a lavorare serenamente come ho fatto in questi anni», conclude. E non intende darsi per vinta. Denuncerà l´accaduto al ministro dell´Istruzione Mariastella Gelmini e al direttore dell´Ufficio scolastico regionale, Guido Di Stefano, sperando che prendano le sue difese. Intanto, si sta consultando con un legale.
L´istituto del piccolo paese in provincia di Palermo ospita 284 alunni di scuola dell´infanzia, primaria e secondaria di primo grado, trovandosi a fare i conti giornalmente con un bilancio sempre più magro. Anche perché dal Comune non arrivano i fondi che tutti gli enti locali dovrebbero erogare alle scuole: da due anni, il Comune non provvede ad erogare i fondi per il funzionamento e la manutenzione
venerdì 13 novembre 2009
mercoledì 28 ottobre 2009
Non importa, una fiera dei Morti è una fiera dei Morti!
Strano, molto strano.
Incrocio Via Libero Grassi - Via degli Emiri, una strada come le altre, non proprio a portata di fiere e mercati rispetto la città essendo un pò fuori porta; una strada con due scuole, un servizio ambulanze, un parcheggio sconfinato non ancora collaudato e un mercato rionale del venerdì che già da solo mette in ginocchio la viabilità della zona.
E cosa accade? in una notte decine di stand vengono tirati su alla stessa velocità con cui, ai tempi della febbre dell'oro, nascevano le cittadine ai fianchi del fiume Yukon.
Stand, stand in mezzo alla strada, lungo i marciapiedi, stand ovunque; stand che per posare in opera necessitano di chiodi piantati per terra a centinaia.
Un mercato per la festa Palermitana dei Morti.
L'organizzazione però puzza...
All'inizio vennero costruiti stand davanti ad un passo carraio di via Nina Siciliana (uscita di un condominio di Via degli Emiri 57) che però, a seguito di forti lamentele, vennero spostati in mezzo alla strada.
Mi vengono dubbi : è mai venuto qualcuno a fare un sopralluogo verificando con il condominio l'eventuale possibilità di usare altri passi carrai? E se l'uscita di via Degli Emiri non fosse carrabile? E se ci fossero stati dei disabili che avevano accesso solo dall'uscita di via Nina Siciliana?
Non importa, una fiera dei Morti è una fiera dei Morti!
Sempre in quel condominio risiede un servizio di Ambulanze con uscita in via Nina Siciliana e mezzi parcheggiati esattamente in via Nina Siciliana (diverse ambulanze e auto)
Altra domanda che mi viene in mente : e ora dove parcheggeranno? come faranno ad essere tempestivi nel soccorso se le ambulanze sono parcheggiate molto lontane dalla sede operativa e, quindi, per raggiungerle bisognerà fare una lunga corsa a piedi?
Non importa, una fiera dei Morti è una fiera dei Morti!
Il venerdì, ogni venerdì, da sempre, in via Libero Grassi viene allestito il mercato rionale autorizzato dal comune, che comporta la chiusura di alcune strade.
Altra domanda che mi viene in mente : ma se con il mercato viene chiusa via Libero Grassi lasciando, all'incrocio con via Degli Emiri, la possibilità di svoltare a sinistra verso via Nina Siciliana, questo venerdì come faranno visto che sarà chiusa anche quella strada?
Mi chiedo anche : ma il comune prima di autorizzare questa fiera ha verificato che il piano traffico, la situazione mercati rionali, le scuole, i servizi sanitari e sociali non venissero penalizzati o addirittura messi in grave difficoltà (dalla Zisa non c'è scelta, bisogna andare in via Perpignano per raggiungere la circonvallazione)?
Non importa, una fiera dei Morti è una fiera dei Morti!
Da parecchio tempo (così come in mezza città) in via Nina Siciliana l'illuminazione pubblica stradale è spenta (è uno scenario inquietante : buio pesto, spazi aperti e molti rischi).
Altra domanda che mi viene in mente : vuoi vedere che li lasciano al buio? No? Tornerà a funzionare? Peggio! Allora vuol dire che una Fiera dei Morti vale più della sicurezza nelle strade!
Non importa, una fiera dei Morti è una fiera dei Morti!
Ancora : i volantini promozionali parlano di fiera dei Morti con accanto "ampio parcheggio"!
Ma come? Il parcheggio sconfinato di cui vi parlavo non è ancora collaudato né inaugurato e per questa fiera pensano di aprirlo?
Altra domanda che mi viene in mente : Non è che per caso l'intenzione è di aprirlo "abusivamente" (ovvero senza previo collaudo)?
Non importa, una fiera dei Morti è una fiera dei Morti!
No, forse sono ingenuo, da un comune retto da un Sindaco che ad agosto veleggia libero al vento pilotato da uno skipper pagato da noi, non posso che aspettarmi questo.
mercoledì 14 ottobre 2009
Amore e Follia
la Follia decise di invitare tutti i sentimenti a prendere un caffè da lei.
Dopo il caffè, la Follia propose:
'Si gioca a nascondino?'
'Nascondino? Che cos'è?' - domandò la Curiosità.
'Nascondino è un gioco. Io conto fino a cento e voi vi nascondete.
Quando avrò terminato di contare, cercherò e il primo che troverò sarà il prossimo a contare.'
Accettarono tutti ad eccezione della Paura e della Pigrizia.
'1,2,3...' - la Follia cominciò a contare.
La Fretta si nascose per prima, dove le capitò.
La Timidezza, impacciata come sempre, si nascose in un gruppo d'alberi.
La Gioia corse in mezzo al giardino.
La Tristezza cominciò a piangere, perché non trovava un angolo adatto per nascondersi.
L' Invidia si unì al Trionfo e si nascose accanto a lui dietro un grande masso.
La Follia continuava a contare mentre i suoi amici si nascondevano.
La Disperazione era disperata vedendo che la Follia era già a novantanove.
'CENTO!' - gridò la Follia - 'Comincerò a cercare.'
La prima ad essere trovata fu la Curiosità, poiché non aveva potuto impedirsi
di uscire per vedere chi sarebbe stato il primo ad essere scoperto.
Guardando da una parte, la Follia vide il Dubbio sopra un recinto che non
sapeva da quale lato si sarebbe meglio nascosto.
E così di seguito scoprì la Gioia, la Tristezza, la Timidezza.
Quando tutti erano riuniti, la Curiosità domandò: 'Dov'è l'Amore?'.
Nessuno l'aveva visto.
La Follia cominciò a cercarlo.
Cercò in cima ad una montagna, nei fiumi sotto le rocce.
Ma non trovò l'Amore.
Cercando da tutte le parti, la Follia vide un rosaio, prese un pezzo di legno e
cominciò a cercare tra i rami, allorché ad un tratto sentì un grido.
Era l'Amore, che gridava perché una spina gli aveva forato un occhio.
La Follia non sapeva che cosa fare.
Si scusò per aver organizzato un gioco così stupido, implorò l'Amore per avere il suo perdono e arrivò al punto di promettergli che l'avrebbe assisito per sempre.
L' Amore, rincuorato, accetto la promessa e quelle scuse così sincere,
così, da allora,
l'Amore è cieco,
e la Follia lo accompagna sempre.
giovedì 8 ottobre 2009
TripleDES bug in LockBox
In seguito ad alcune analisi del codice sorgente della suite Lockbox, ho scoperto l'arcano.
Quando vengono criptati solamente 8 byte, le funzioni di crittografia aggiungono erroneamente altri 8 byte vuoti in coda al flusso da criptare; esattamente come se stessimo criptando un flusso di byte NON multiplo di 8 byte.
L'errore di fondo, nel codice, consiste nell'aggiungere un blocco di 8 byte senza verificare se il flusso sia già multiplo di 8 byte.
Di seguito la riga di codice principale responsabile dell'errore nella funzione TripleDESEncryptStream della unit LbProc di LockBox.
1. If Encrypt Then
2. Inc(BlockCount);
Ho risolto il problema riscrivendo la funzione in toto (considerato il fatto che non mi piace come è stata concepita).
L'unica vera differenza nella funzione scritta da me è legata al fatto che la utilizzo esclusivamente con SmartCard e, pertanto, trovo comodo che i parametri siano di tipo Array di Byte, piuttosto che Stream.
Ecco di seguito il codice sorgente.
1.Procedure TripleDes(const Source: Array Of Byte;
2. const Key: TKey128;
3. var Dest: TAnyArray;
4. Encrypt: Boolean);
5.
6. Function CheckBlockSize(fBlock : TDESBlock) : Byte;
7. Var
8. Last : Byte;
9. Begin
10. Last:=1;
11. While (Last<=SizeOf(fBlock)) And (fBlock[Last-1]<>0) Do
12. Inc(Last);
13. Result:=Last-1;
14. End;
15.
16.Var
17. I : LongInt;
18. Block : TDESBlock;
19. Context : TTripleDESContext;
20. BlockMod,
21. BlockCount : LongInt;
22.
23. InStream : TMemoryStream;
24. OutStream : TMemoryStream;
25.Begin
26. InStream := TMemoryStream.Create;
27. OutStream := TMemoryStream.Create;
28. Try
29. InStream.Write(Source[0], Length(Source));
30. InStream.Position := 0;
31.
32. InitEncryptTripleDES(Key, Context, Encrypt);
33.
34. BlockMod:=(InStream.Size Mod SizeOf(Block));
35. BlockCount := (InStream.Size Div SizeOf(Block));
36.
37. For I := 1 To BlockCount Do
38. Begin
39. InStream.Read(Block, SizeOf(Block));
40. EncryptTripleDES(Context, Block);
41. // scrittura ultimo blocco in decrypt
42. If Not Encrypt And (I=BlockCount) Then
43. OutStream.Write(Block, CheckBlockSize(Block))
44. Else
45. OutStream.Write(Block, SizeOf(Block));
46. End;
47.
48. // scrittura ultimo blocco in encrypt
49. If Encrypt And (BlockMod<>0) Then
50. Begin
51. FillChar(Block,SizeOf(Block),0);
52. InStream.Read(Block, BlockMod);
53. EncryptTripleDES(Context, Block);
54. OutStream.Write(Block, SizeOf(Block));
55. End;
56.
57. OutStream.Position := 0;
58. SetLength(Dest, OutStream.Size);
59. OutStream.Read(Dest[0], OutStream.Size);
60. Finally
61. InStream.Free;
62. OutStream.Free;
63. End;
64.End;
E' possibile estrarre la funzione dalle Unit LockBox e scriverla in una propria aggiungendo alla lista delle uses le seguenti:
1.Uses
2. LbCipher,
3. lbProc,
4. LbString;
giovedì 24 settembre 2009
martedì 15 settembre 2009
Bugie, sempre bugie, mai raccontate
"Saranno inaugurate domani le case realizzate a Onna con i fondi raccolti dalla Croce rossa. Si tratta delle prime case di legno per le quali la Croce Rossa ha impiegato 5 milioni e 200 mila euro: 94 unita' abitative costruite su iniziativa della Protezione civile su progetto realizzato dalla Provincia autonoma di Trento.
La cerimonia d'inaugurazione del Villaggio Croce Rossa domani alle 15:00, alla presenza del presidente del Consiglio Silvio Berlusconi, del capo della Protezione civile Guido Bertolaso e del commissario della Croce Rossa Italiana Francesco Rocca."fonte : Rai News 24
Altro che le case "di Berlusconi"...
lunedì 14 settembre 2009
Rhynchophorus ferrugineus
Rhynchophorus ferrugineus 2
Inserito originariamente da William Pristia
L'artefice della strage di Palme...
giovedì 3 settembre 2009
Goccia 8 Acqua su acqua
Goccia 8 Acqua su acqua
Inserito originariamente da William Pristia
Quale esperimento per definire il setup e finale ed ecco il risultato. Foto scattata rigorosamente in casa...
venerdì 28 agosto 2009
Un nuovo modo per organizzarsi le partite di calcetto a Palermo
Disponibile da adesso e operativo dal 7 settembre 2009, www.calcettopalermo.com consente
di iscriversi liberamente e gratuitamente ai servizi offerti, permettendo cosi a tutti di poter consultare i campi disponibili, i posti di eventuali partite organizzate da altri (e aperte a tutti), e altro ancora.
Piuttosto che preoccuparsi di telefonare ai campi alla ricerca di posti liberi per giocare, si può tenere sotto controllo la propria situazione ovunque ci si trovi, tramite internet e ricevere le email di avviso sulle attività prossime.
Un'idea davvero originale ed utilissima.
martedì 25 agosto 2009
DB firebird da 1 TB
domenica 19 luglio 2009
Precari? Beati loro!
Ora brilla, luccica e profuma (mi chiedo come mai si è partiti dal sottopasso che collega direttamente la città al BINGO, per altro sequestrato tempo fa per implicazioni mafiose).
Sapete il nostro Comume poverissimo di fondi cosa fa?
Assume QUARANTA persone come PRECARI per un costo di 24000 euro al mese totali (avete letto bene, VENTIQUATROMILA) per vigilare sul posto. QUARANTA persone.
Oggi, dopo appena un giorno di lavoro i nostri amici precari HANNO FATTO ISTANZA PER LA STABILIZZAZIONE...
Che studiate a fare? Fate i precari che poi vi stabilizzano...(a meno che non siete dei poveri insegnanti, allora non vi stabilizzeranno mai...)
Ma alle prossime elezioni comunali, a Cammarata, non dimenticate di votarlo, come sempre accade!!!
venerdì 3 luglio 2009
Buon compleanno amore mio
venerdì 26 giugno 2009
Addio per sempre Michael
Nessuno mai più sarà come Michael Jackson;
nessuno mai più scriverà musica al livello di Billie Jean, Trhiller, Dirty Diana,
nessuno mai più avrà dietro se 45 anni di carriera su 50 di vita.
Rest In Peace Jacko...
giovedì 4 giugno 2009
La colpa è mia per l'immondizia a Palermo?
Ma scusate? Ora la colpa è mia di tutto questo? A che titolo chiedi scusa a nome mio? Come ti sei permesso a dare la colpa a me? E poi...Ai turisti? DEVI CHIEDERE SCUSA PRIMA AI PALERMITANI!
venerdì 22 maggio 2009
Gli italiani, negati per la democrazia
Eppure è la terza carica di stato.
Gianni Alemanno, parente di quel Pino Rauti biografo di Mussolini e ideologo dell'estrema destra, è il sindaco di Roma, preferito dagli elettori al candidato della sinistra, non solo presente per dovere d'ufficio a tutte le commemorazioni dell'antifascismo (a cominciare da quella per le Fosse Ardeatine), ma anche dell'antisemitismo.
Sindaco di Roma come lo era di Lecce la neofascista Adriana Poli Bortone, che richiesta di un parere sui miei scritti antifascisti, disse, giustamente dal suo punto di vista, che sembravano repellenti.
E' il ministro della Difesa, tutore della sicurezza democratica e oratore ufficiale della celebrazione del 25 aprile, data sacra alla Resistenza al nazifascismo, Ignazio La Russa, figlio e fratello di fascisti eccellenti, e non dimentichiamo il Presidente del Consiglio Silvio Berlusconi, che, alla vigilia di una elezione romana, richiesto su chi preferisse tra il candidato di destra e quello di sinistra, non ci pensò un attimo a fare il nome del primo, aprendo la strada allo “sdoganamento”, così venne chiamato, degli ex fascisti e sempre fascisti, che con la grande manovra trasformista di Fiuggi, si erano ribattezzati in Alleanza Nazionale.
Oggi il trasformismo dei fascisti di prima, neofascisti poi, è arrivato al punto massimo, ma chi sa se definitivo, che li vede non solo ricoprire le più alte cariche dello Stato, ma fra i più attenti difensori della democrazia, i primi nella sua difesa dalle tentazioni autoritarie del sultano di Arcore.
Che accade nel Bel Paese?
Quello che è sempre accaduto : le ideologie passano, la voglia di potere resta. La tradizione più forte della nostra idea forte in politica resta "Francia o Spagna purchè se magna".
Il fascismo che va e che torna come “autobiografia della nazione”?
Giuseppe Prezzolini diceva :
“Di una cosa son certo : gli italiani mi sembrano negati alla democrazia; islandesi, svizzeri, inglesi, americani, son nati democratici, noi autoritari e faziosi. Forse non sono stato fascista perchè ero troppo poco italiano”.
Giorgio Bocca.
------------------
Io personalmente, invece, aggiungo che questo nero periodo in cui la politica ormai è alla mercè delle onde del mare, alla deriva, dobbiamo essere più preoccupati che mai.
Nella storia, le fasi antecedenti i regimi e le dittature sono caratterizzate dalla "morte della politica", un chiaro meccanismo volto ad "assassinare la politica" per spianare la strada alla dittatura.
martedì 19 maggio 2009
[Delphi] Un Class Helper per TStringList
L'utilizzo è banalissimo, per una qualsiasi istanza di TStringlist :
1.Var
2. MyStrings : TStringList;
3. lIndex : Integer;
4.Begin
5. MyString:=TStringList.Create;
6. MyString.Add('Prova 1');
7. MyString.Add('Prova 2');
8. MyString.Add('Prove 3');
9. MyString.Add('Prove 4');
10. MyString.Add('Provo 5');
11. lIndex:=MyString.FindByPart('Prove');
12. If lIndex<>-1 Then
13. Begin
14. // Trovato Prove in MyString[lIndex];
15. End;
16.End;
Di seguito il codice dell'Helper :
1.Interface
2.
3. TStringListHelper = Class Helper For TStringList
4. Public
5. // True se aSubString Š contenuta in una delle righe
6. // a partire dalla riga StartFrom;
7. // Restituisce la prima riga con l'occorrenza
8. Function FindByPart(Const aSubString : String;
9. Var aIndex : Integer;
10. Const StartFrom : Integer = -1) : Boolean; Overload; Inline;
11. Function FindByPart(Const aSubString : String) : Boolean; Overload; Inline;
12. // Scorre le righe a partire dalla riga StartFrom
13. // sino a trovare la prima riga aIndex non vuota
14. Procedure FindNextLine(Var aIndex : Integer; Const
15. StartFrom : Integer = -1); Inline;
16. // True se aSubString Š contenuta in una delle righe
17. // a partire dalla riga StartFrom
18. Function Contain(Const aSubString : String;
19. Const StartFrom : Integer = -1) : Boolean; Inline;
20. End;
21.
22.Implementation
23.
24.function TStringListHelper.FindByPart(const aSubString: String;
25. Var aIndex: Integer;
26. Const StartFrom : Integer = -1): Boolean;
27.Var
28. S,
29. I : Integer;
30. C : Integer;
31.begin
32. aIndex:=-1;
33. Result:=False;
34. If Self.Count>0 Then
35. Begin
36. S:=0;
37. C:=Pred(Self.Count);
38. If (StartFrom>=0) And (StartFrom<(C+1)) Then S:=StartFrom;
39. For I:=S To C Do
40. Begin
41. If Pos(aSubString,Self[I])<>0 Then
42. Begin
43. aIndex:=I;
44. Result:=True;
45. Break;
46. End;
47. End;
48. End;
49.end;
50.
51.function TStringListHelper.FindByPart(const aSubString: String): Boolean;
52.Var
53. S,
54. I : Integer;
55. C : Integer;
56.begin
57. Result:=False;
58. S:=0;
59. C:=Pred(Self.Count);
60. For I:=S To C Do
61. Begin
62. If Pos(aSubString,Self[I])<>0 Then
63. Begin
64. Result:=True;
65. Break;
66. End;
67. End;
68.end;
69.
70.procedure TStringListHelper.FindNextLine(var aIndex: Integer;
71. const StartFrom: Integer);
72.Var
73. S,
74. I : Integer;
75. C : Integer;
76.begin
77. aIndex:=-1;
78. S:=0;
79. C:=Pred(Self.Count);
80. If (StartFrom>=0) And (StartFrom<(C+1)) Then S:=StartFrom;
81. For I:=S To C Do
82. Begin
83. If Trim(Self[I])<>'' Then
84. Begin
85. aIndex:=I;
86. Break;
87. End;
88. End;
89.end;
90.
91.function TStringListHelper.Contain(const aSubString: String;
92. const StartFrom: Integer): Boolean;
93.begin
94. If (StartFrom>=0) And (StartFrom<(Pred(Self.Count)+1)) Then
95. Result:=(Pos(aSubString,Self[StartFrom])<>0)
96. Else
97. Result:=False;
98.end;
lunedì 18 maggio 2009
Supporto firebird per le future versioni Delphi
- Project Weaver
- Main Themes
- User Experience
- Enhance Connectivity
- Documentation
- IDE usability
- Team Productivity
- Touch
- IDE – Insight (easy Keyboard access to almost everything)
- Improvements to DataSnap
- Firebird Support
- .NET AOP
- SCM Support
- Enhanced RTTI Support
- Attribute Support
- Seamless .NET <> Native communication
- Windows 7 APIs and Direct 2D
- Full Support of SOAP 1.2 Clients
- Project X
- Cross-platform Windows, Mac OS, and Linux
- Cross-platform component library
- DataSnap on all platforms
- Project Chromium, Quality, Quality
- Quality, Quality, Quality
- Pascal Code Formatter
- Documentation of the OTA
- New Data binding model allowing binding to almost any property on a control
- More integration with the database tools.
- Project Commodore
- 64 Bit native
- Full compiler, RTL and VCL support for 64 native
- Multi-Core. Multi-threaded applications.
Un mondo fatto da coglioni...
l'Unione Europea ha frainteso,
l'Onu ha frainteso,
Tutti coglioni e un solo ZAR...
lunedì 11 maggio 2009
E si...Silvio è il più popolare del mondo...
lunedì 4 maggio 2009
Desidero pubblicare un sondaggio vero di France24 e dell’Herald Tribune, in cui è mostrata la popolarità dei leader del mondo, compreso il pluridivorziato, plurindagato, plurimiliardario Silvio Berlusconi.
Il Presidente del Consiglio afferma da molto ormai di essere il leader più popolare del mondo (non per le sue cazzate, come noi dovremmo pensare), sondaggi fatti come sempre da agenzie di suo piacere...
Questi sono i risultati di sondaggi veri.
sabato 2 maggio 2009
Discutere fa bene sempre...
Non ditemi che è una questione di regime fiscale...per favore...
martedì 21 aprile 2009
Esecuzione di comandi WSQL
Questa guida di riferimento è indirizzata agli sviluppatori WY
L'esecuzione di un comando SQL/WSQL compilato con il metodo discusso nella Guida di riferimento per la creazione di comandi SQL da codice Delphi, come da esempio seguente :
SqlCMD.BuildSQL('Descrizione comando sql');
La richiesta di esecuzione del comando può avvenire in due metodi differenti. Il primo metodo di esecuzione non ritorna un cursore al comando ed è adatto per comando DML (manipolazione dei dati) e DDL (definizione dello schema), mentre il secondo metodo ritorna un cursore alle righe restituite dall'esecuzione del comando. questo fa comprendere che il metodo di esecuzione va scelto a priori in funzione del comando. Vedremo per primo il metodo di esecuzione che non ritorna cursori, come in questo caso :
1.With WYDM, WYDM.SQLServices Do
2.Begin
3. TransactionStart;
4. Try
5. ExecuteSQL(SqlCMD.BuildSQL('Descrizione'), stWithSQL);
6. TransactionCommit;
7. Except
8. TransactionRollBack;
9. End;
10.End;
Il metodo che esegue il comando è ExecuteSQL appartenente a WYDM, il modulo dati dell'applicazione. In ingresso questo metodo si aspetta il comando SQL compilato (restituito da BuildSQL) e la modalità di gestione del comando che può essere :
- stWithSQL, per comandi DML
- stWithPSQL, per comandi DDL
Vediamo ora il caso più completo che, invece, esegue il comando ritornando un cursore molto semplice e potente da utilizzare.
1.Var
2. lRow : TWYDataset;
3.Begin
4. lRow := WYDM.CreateFetchableDataset;
5. Try
6. With WYDM, WYDM.SQLServices Do
7. Begin
8. SqlCMD.Clear;
9. SqlCMD.Sql.Add('SELECT * FROM WY_ALIAS');
10. SqlCMD.Sql.Add(' WHERE IDALIAS=?1?');
11. SqlCMD.AV(aAlias);
12. If ExecuteSQL(SqlCMD.BuildSql('Recupero Alias'),'IDALIAS', lRow, flMultiTone) <> '' Then
13. Begin
14. While FetchRow(lRow, flMultiTone) Do
15. Begin
16. lRow.Row.FieldByName('TIPOLOGIA_ALIAS').AsInteger;
17. End;
18. End;
19. End;
20. Finally
21. WYDM.FreeFetchableDataset(lRow);
22. End;
23.End;
Esaminiamo il codice.
Le righe da 8 a 11 dovrebbero ormai essere chiare, mentre sono di nostro interesse le righe 4,12,14,16 e 21.
La riga 4 inizializza il cursore lRow e lo predispone per ricevere il dataset. Uno dei punti forti di WY è la gestione completamente offline dei dataset pertanto, una volta eseguito il nostro comando, il cursore lRow conterrà il dataset in memoria e le risorse per l'esecuzione del comando SQL/WSQL saranno già tutte rilasciate. Vedremo quindi più avanti tutte le caratteristiche del cursore TWYDataset.
La riga 12 esegue il comando. Il metodo si aspetta il comando SQL compilato, il nome di una colonna chiave, il cursore e la modalita di gestione del cursore stesso. Concentriamoci sull'ultimo parametro, che può assumere due valori :
- flSingleTone
- flMultiTone
Nel primo caso ci si aspetta il ritorno di una sola riga (quindi per le query singletone), mentre nel secondo ci si aspetta un dataset. A prescindere dalle righe ritornate, il cursore lRow punterà alla prima riga del dataset in memoria.
Ciò che ora ci interessa è accedere ai valori della riga corrente nel dataset, e poter scorrere il dataset stesso.
L'accesso ai dati della riga corrente avviene come in un qualsiasi dataset derivato da TDataset che, nel nostro cursore, è puntato dall'attributo Row del cursore lRow, come descritto nella riga 16 dell'esempio precedente e qui di seguito generalizzato :
lRow.Row.FieldByName('COLONNA_INTERO').AsInteger;
Per scorrere invece il dataset in memoria tramite il cursore consideriamo la riga 14 dell'esempio precedente, qui generalizzato :
While FetchRow(lRow, flMultiTone) Do
Non è necessario aprire o chiudere i cursori lRow in quanto sarà compito dell'oggetto WYDM gestire il flusso. La differenza con l'approccio classico di gestione dei dataset sta proprio nel fatto che l'apertura e la chiusura, i controlli di esistenza e altro vengono svolti dall'oggetto WYDM in modo trasparente.
La riga 21 dell'esempio precedente rilascia le risorse di memoria allocate dal cursore lRow.
E' infine possibile eseguire il comando per leggere il valore di una sola colonna in una query singletone con il seguente metodo :
lString:=ExecuteSQL(SqlCMD.BuildSql('Descrizione'), 'NOME_COLONNA');
domenica 19 aprile 2009
Preparazione di comandi WSQL
Questa guida di riferimento è indirizzata agli sviluppatori WY
Il modeler
WY dispone di un oggetto SQLCMD, attributo dell'oggetto WYDM (il modulo dati base per le applicazioni WY) progettato per la creazione di comandi SQL e WSQL.
La struttura essenziale della classe TWYSQLModeler (SQLCMD ne è un'istanza) è la seguente.
1. TWYSQLModeler = Class Sealed(TWYObject)
2. Public
3. SQL : TStringList;
4. Procedure Clear;
5. Function FAV(Const aValue : Variant;
6. AddQuotes : Boolean = True): TWYSQLModeler;
7. Function AV (Const aValue : Variant;
8. AddQuotes : Boolean = True): Boolean;
9. Function AN : Boolean;
10. Function AC (Const aCondition : String;
11. ConditionType : TConditionType;
12. DoItOnlyIf : Boolean) : Boolean;
13. Function BuildSQL (aOwner : String = '';
14. AutoClear : Boolean = False): String;
15. End;
Della dichiarazione di cui sopra presteremo particolare attenzione all'oggetto SQL della riga 3, ai metodi FAV,AV,AC,AN e BuildSQL.
Per meglio comprendere l'utilizzo dell'oggetto, è bene proseguire con la descrizione del processo di creazione.
- Scrittura del comando tramite l'oggetto SQL;
- Definizione delle condizioni variabili;
- Passaggio dei parametri variabili;
- Compilazione del comando.
Scrittura del comando SQL/WSQL
La scrittura del comando è eseguita mediante l'oggetto SQL di SQLCMD.
1. // ...
2. With WYDM.SqlServices, WYDM Do
3. Begin
4. SqlCMD.Clear;
5. SqlCMD.Sql.Add('SELECT * FROM TABELLA WHERE ...');
6. // ...
7. End;
Definizione delle condizioni variabili
Le condizioni variabili aggiungono condizioni al comando SQL/WSQL in modo dinamico.
SqlCmd.AC('COLONNA1=?1?', ctAND, Condizione1);
La riga di questo esempio segue la scritta del comando, ovvero va inserita dopo la riga 6 dell'esempio precedente.
Il parametro in cui è inserito come esempio il valore 'COLONNA1=?1?' dovrà contenere la condizione da passare al comando.
Il parametro ctAND specifica che questa condizione va agginuta al comando con AND.
Il parametro Condizione1 è, infine, lo statement delphi che se vero cosentirà di aggiungere la condizione al comando.
SqlCmd.AC('TIPOLOGIA_ALIAS<>1',ctAND,(cb_AliasCheck.Checked = True));
In questo esempio al comando viene aggiunta in AND la condizione TIPOLOGIA_ALIAS<>1 solo se il checkbox cb_AliasCheck ha la proprietà checked=true. La condizione dinamica prevede che il comaando SQL abbia al suo interno inserita una richiesta di condizione dinamica del tipo @n@.
Definizione dei parametri variabili
I parametri variabili aggiungono parametri al comando SQL/WSQL in modo dinamico.
1.SqlCmd.AV(WYAM.GlobalManager.GlobalID);
2.SqlCmd.AV(Valore1);
3.SqlCMD.AN;
In questo esempio alle righe 1 e 2 vengono passati due parametri di applicazione, sia globali (WYAM.GlobalManager.GlobalID) che locali (IDTabella). Alla riga 3, invece, viene passato NULL.I tre parametri passati in questo esempio prevedono che il comando SQL abbia al suo interno inserite 3 richieste di valori dinamici del tipo ?n?,ovvero che la corrispondente Query sia così composta :/p>
1.SELECT A.ID_AZIENZA, A.DENOMINAZIONE_AZIENZA
2. FROM APP_AZIENDE A
3. WHERE A.ID_AZIENDA=?1? AND A,CODICE_FISCALE=?2? AND
4. COALESCE(A.AZIENDA_CHIUSA,?3?);
Un altro metodo per passare i valori ai parametri variabili è quello del Fluent Interfaces, ovvero :
SqlCmd.FAV(Valore1).FAV(Valore2).FAV(Valore3);
Vediamo ora un esempio di codice completo per la scrittura del comando.
1. With WYDM.SqlServices, WYDM Do
2. Begin
3. SqlCmd.Clear;
4. SqlCmd.Sql.Add('SELECT *');
5. SqlCmd.Sql.Add('FROM ');
6. SqlCmd.Sql.Add(' APP_AZIENDE A');
7. SqlCmd.Sql.Add('WHERE A.IDAZIENZA=?1? @1@');
8. SqlCmd.AC('A.DENOMINAZIONE_AZIENDA=?2?', ctAND, Condizione1);
9. SqlCmd.AV(WYAM.GlobalManager.GlobalID);
10. SqlCmd.AV(ValoreColonna2);
11. //...
12. End;
Facciamo ora un esempio più chiaro e complesso in cui con una interogazione in WSQL vogliamo conoscere quali utenti sono stati attivati dopo una certa data. Per eseguire questo comando dobbiamo accertarci che l'utente connesso abbia i permessi di amministratore, altrimenti mostreremo solamente i dati relativi all'operatore connesso.
1.Var
2. lData : TDateTime;
3.Begin
4. lData:=StrToDateTimeDef('01/01/2008',Date);
5. With WYDM,WYDM.SQLServices Do
6. Begin
7. SqlCMD.Clear;
8. SqlCMD.Sql.Add('SELECT');
9. SqlCMD.Sql.Add(' IDOPERATORE,NOMINATIVO_OPERATORE,');
10. SqlCMD.Sql.Add(' DATA_ATTIVAZIONE');
11. SqlCMD.Sql.Add('FROM');
12. SqlCMD.Sql.Add(' WY_OPERATORI O');
13. SqlCMD.Sql.Add('WHERE');
14. SqlCMD.Sql.Add(' O.IDAPPLICATIVO=?1? AND');
15. SqlCMD.Sql.Add(' O.DATA_ATTIVAZIONE>=?2?');
16. SqlCMD.Sql.Add(' @3@');
17. SqlCMD.AC('O.IDOPERATORE=?3?',ctAND,(Not WYAM.AppUserAdmin));
18. SqlCMD.AV(WYAM.ApplicationID);
19. SqlCMD.AV(lData);
20. SqlCMD.AV(WYAM.AppUserID);
21. SQLCMD.BuildSQL('Operatori nuovi');
22. End;
23.End;
In questo esempio, la verifica della proprietà WYAM.AppUserAdmin è determinante per l'aggiunta della condizione variabile. Condizione che viene aggiunta (vincolando quindi a mostrare la sola riga dell'operatore connesso) solo se l'utente non è amministratore. E' importante prestare attenzione al fatto che l'ordine di aggiunta dei parametri variabili è strettamente connesso al numero di richiesta di valore dinamico ?n?. Questo significa che il valore lData deve essere aggiunto in seconda posizione, avendo nel comando SQL numero di richiesta pari a ?2?. Notare che il metodo AV ha per parametro in ingresso un Variant e pertanto, oltre al vantaggio di una semplice gestione dei dati passati ai comandi, viene semplificata anche la procedura di conversione dati per il DB.
Compilazione del comando
La compilazione del comando genera un comando SQL completo di parametri e condizioni.
SqlCMD.BuildSQL('Descrizione comando sql');
Siamo ora pronti ad eseguire il comando.