Italian SQLite e SQLiteCipher

AlpVir

Well-Known Member
Licensed User
Longtime User
A seconda della versione dell'app devo usare un db SQLite oppure un db SQLiteCipher.
L'ideale, ma temo impossibile da realizzare, sarebbe un codice del tipo
B4X:
Dim Versione as string="1"         '  fra qualche tempo cambierò in "2"
If Versione=1 then
   dim db  as SQL
else
   dim db   as SQLCipher
end if
Il tutto - attenzione - inserito in Process_Globals (la variabile db deve essere globale).
Poi, all'interno dell'app, posso facilmente scrivere :
B4X:
If Versione=1 then
   db.Initialize (File.DirRootExternal,NomeFileNonCifrato,False)
else
   db.Initialize (File.DirRootExternal,NomeFileCifrato,False,Psw,"")
end if
Da qui in poi il codice sarebbe uguale sia per il db non cifrato che per quello cifrato, con grandissima semplificazione del codice da scrivere.
In alternativa sarei costretto a scrivere in Process_Globals
B4X:
dim db     as SQL
dim dbC   as SQLCipher
con un significativa e rilevante complicazione - qui non evidente - della scrittura del codice.
 

sirjo66

Well-Known Member
Licensed User
Longtime User
hai un problema che si chiama "late binding", qui trovi un po' di informazioni, ma cerca su internet e ne troverai moltissime
https://it.wikipedia.org/wiki/Binding

Per risolvere il problema bisognerebbe avere il compilatore condizionale, cioè che se stiamo digitando del codice sull'IDE esegue solo certe righe, ma se siamo sul compilato ne esegue altre, su VB.NET si usa:
#If DEBUG Then

Prova a fare questa cosa: definire la variabile db come un oggetto qualsiasi su Process_Globals con
Dim db As Object
e vedi se compilando ti dà errore sulla riga
db.Initialize (File.DirRootExternal,NomeFileNonCifrato,False)

se non ti dà errore siamo a cavallo
 

udg

Expert
Licensed User
Longtime User
Non è per caso questo ciò che ti occorre?
 

AlpVir

Well-Known Member
Licensed User
Longtime User
Grazie udg, ma non è questo. Avrei voluto che l'app fosse la assolutamente stessa ma reagisse in diverso modo a seconda della sua versione.
Ho comunque risolto il problema in altro modo, convertendo tutta l'app ad interagire con SQLcipher, lasciando perdere il normale SQLite.
 

sirjo66

Well-Known Member
Licensed User
Longtime User
in VB.NET la cosa si risolve in maniera elegante.
Come su B4A si definisce un "Conditional Symbols", ad esempio "Sviluppo", e poi queste righe:
B4X:
#If Sviluppo
    Dim db As Sql
#Else
    Dim db As Object
#End If
In modalità di sviluppo quindi attivo la variabile Sviluppo, e il compilatore riesce a compilare, ma soprattutto a mostrarmi l'help di tutti i metodi e proprietà della variabile db poichè definita correttamente.
Poi quando dovrò distribuire il programma disattivo la variabile Sviluppo e ricompilo il tutto, in questo caso la variabile db sarà un object generico e quindi posso anche associarla ad altre cose in fase di runtime (questo viene fatto soprattutto quando si deve accedere a driver di cui non si conosce la versione installata dal cliente, ad esempio per MySQL).
Se il compilatore VB.NET trova una riga db.Execute(query) la compila senza problemi e non dà nessun avviso, sarà poi in fase di runtime che controlla se esiste o no il metodo Execute, ma se B4A invece non riesce a compilare il tutto purtroppo non c'è nulla da fare.
Bisognerebbe chiamare il metodo Execute tramite il suo nome, ad esempio CallSub(db, "Execute", "parametri da passare") ma non so se si riesce a trovare il sistema per farlo.

Maggiori info (in italiano) su http://nuke.vbcorner.net/Articles/V...Outlook/tabid/107/language/it-IT/Default.aspx
 
Top