Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Sqlite, firedac e Ftp

241 views
Skip to first unread message

jax2...@gmail.com

unread,
Feb 8, 2018, 7:24:29 PM2/8/18
to
Salve a tutti, scrivo per ottenere un vostro prezioso supporto/consiglio.
Sto realizzando una semplice rubrica per Android tramite Delhi 10, firemonkey e firedac. Il db che utilizzo per salvare i numeri di telefono nella memoria interna dello smartphone è SQLite.
Vorrei fare un'implementazione al programma, ossia sincronizzare i dati della rubrica prendendoli da un database salvato su un server. Poiché non ne so nulla di programmazione client/server, REST e datasnap mi è venuto in mente di usare Ftp. Nello specifico, pensavo di fare questo: alla pressione del pulsante"aggiorna" chiudo il database, cancello il file originale, scarico il database dal server tramite ftp, riapro il database. Sono riuscito a scrivere il codice ma c'è qualcosa che non va poiché ricevo un errore sql/firedac che mi dice:
"The database disk image is malformed".

Cosa può essere successo? È corretto secondo voi questo procedimento? Ftp, applicato al mio caso specifico, può servirmi per ottenere ciò che vorrei fare?

Grazie a tutti in anticipo.

Alberto Salvati

unread,
Feb 10, 2018, 5:43:11 AM2/10/18
to
Ciao.
Prima di tutto, usare delphi per lo sviluppo android non va bene.
Lo strumento per sviluppare app android è android studio, punto.
Ho sentito parlar bene di xamarin ma non avendolo mai usato, non dico nulla.

A parte questo, potresti essere più preciso sul "chiudo il database"?
Tu hai la connessione al db sempre attiva?


> scrivere il codice

Postalo qua e vediamo


> "The database disk image is malformed".

2 prove rapide da fare...

1) collegati al tuo ftp da un qualcosa che non sia la tua app e scaricati il file, poi prova ad aprirlo.

2) collega il tuo device al pc e, usando la shell di adb copiati il file sul pc, prova ad arpire questa copia e vedi cosa succede

A.

a.laf...@gmail.com

unread,
Feb 10, 2018, 12:41:16 PM2/10/18
to
On Saturday, 10 February 2018 10:43:11 UTC, Alberto Salvati wrote:

[...]
> Lo strumento per sviluppare app android è android studio, punto.

Questo e` un tuo teorema. Ci sono vari modi per sviluppare su Android e Android Studio e` solo uno di questi. Se non conosci Xamarin, come fai a dirlo?

jax2...@gmail.com

unread,
Feb 10, 2018, 6:58:33 PM2/10/18
to
Ciao Alberto, innanzitutto grazie per avermi risposto.

Uso Delphi per lo sviluppo di applicazioni Android in quanto per prima cosa amo questo linguaggio alla follia :-) e poi perchè sono solo un appassionato di informatica e non lo faccio di mestiere, per cui non avrei proprio il tempo materiale di studiarmi ex novo un linguaggio.


Ti posto il codice associato all'evento OnClick di un pulsante:

FDConnection1.Connected := false;

DeleteFile(TPath.GetDocumentsPath + PathDelim + 'database.s3db');

IdFTP1.Host := 'nomehost';
IdFTP1.Username := 'user';
IdFTP1.Password := 'pass';
IdFtp1.Passive := false;
IdFtp1.ConnectTimeout := 1000;
try
IdFtp1.Connect();
except
ShowMessage('impossibile connettersi');
end;

if IdFTP1.Connected then
begin
IdFtp1.BeginWork(wmRead);
IdFTP1.ChangeDir( '/' );
if not FileExists('database.s3db') then
begin
IdFTP1.Get( 'database.s3db', TPath.GetDocumentsPath + PathDelim +
'database.s3db', true, false);
end;

IdFtp1.Disconnect();
end;

FDConnection1.Params.Values['Database'] :=
TPath.Combine(TPath.GetDocumentsPath, 'database.s3db');
FDConnection1.Connected := true;
FDQuery1.Active := true;


Quando clicco sul pulsante mi compare il seguente errore: [FireDAC][Phys][SQLite] ERROR: malformed database schema (?)


L'errore mi compare anche se sul server ftp carico lo stesso database originale.

Ripeto, è una soluzione alternativa che mi è venuta in mente per aggiornare da remoto i dati del db poichè non conosco la programmazione client/server.

Grazie!

a.laf...@gmail.com

unread,
Feb 11, 2018, 5:44:47 AM2/11/18
to
On Friday, 9 February 2018 00:24:29 UTC, jax2...@gmail.com wrote:

[....]
Nello specifico, pensavo di fare questo: alla pressione del pulsante"aggiorna" chiudo il database, cancello il file originale, scarico il database dal server tramite ftp, riapro il database.

Quindi se hai un problema nello scaricamento dei dati nuovi, hai perso i dati vecchi? Non ti serve cancellare il file, ti basta cancellare il contenuto delle tabelle e reimportarle dal file esterno.

> "The database disk image is malformed".
> Cosa può essere successo?

http://bfy.tw/GXgU

> È corretto secondo voi questo procedimento?

No.

>Ftp, applicato al mio caso specifico, può servirmi per ottenere ciò che vorrei fare?

No.

Varrebbe la pena imparare come connettersi ad un db remoto ed importare i dati da esso. Non e` cosi` complicato.

alessandrob

unread,
Feb 11, 2018, 10:10:18 AM2/11/18
to
Io cercherei di separare i problemi:

a) fare il download di un file via ftp
b) aggiornare un database rispetto ad una origine dati

Per il primo punto che il file sia un DB conta poco.
Devi riuscire a far funzionare il download in modo che il file che viene scaricato sia identico a livello binario (stessa dimensione, stessi byte, ...)

Per il secondo punto, in passato anch'io ho seguito una strada simile (scaricavo in realtà una tabella alla volta e non il database completo)

Ora ho realizzato (con parecchio lavoro) una gestione di sincronizzazione incrementale, in modo da non dover ogni volta ri-aggiornare tutto.

Il limite infatti del metodo che stai seguendo è la dimensione dei dati che devi scaricare.

Se si limitano a poche centinaia di record funziona correttamente.
Quando la dimensione arriva a migliaia, decine di migliaia o (come nel mio caso) centinaia di migliaia di record anche i tempi di sincronizzazione diventano importanti

Per ultimo, riguardo al consiglio di connetterti al DB da remoto avrei una critica: di solito quando utilizzi un DB remoto viene impostato nel server che questo possa essere utilizzato solo da applicazioni locali (per ragioni di sicurezza).

Per poter accedere da remoto devi quindi aprire delle porte nel firewall per consentire l'accesso: le porte sono standard e quindi attaccabili...

Io ho preferito seguire la strada di un web service (scritto per l'occasione in PHP) che fa da interfaccia tra le mie chiamate e il DB remoto.

Avrei anche potuto scrivere una applicazione con RAD Studio 10.2 in linux, ma la pigrizia e il tempo a disposizione mi ha fatto optare per PHP.
P.S. io utilizzo solo server Linux esposti nel web (è una scelta personale)

alessandrob

unread,
Feb 11, 2018, 10:17:14 AM2/11/18
to
Vorrei fare una aggiunta circa quanto riguarda utilizzare Delphi per sviluppare una APP Android.

Sicuramente per un nuovo progetto è valido il suggerimento di strumenti diversi.

Ma se devi "riutilizzare" parte del tuo codice?
E se devi fare una applicazione che possa girare anche su IOS o MAC?

Personalmente ho una APP che ho scritto in Delphi (Android) nella quale ho riutilizzato circa 500.000 linee di codice... tratte da uno dei miei progetti a cui lavoro da anni che ha circa 2.100.000 linee di codice

Quanto tempo avrei impiegato a riscrivere quelle righe?

N.B. Ovviamente questo è il mio parere personale

jax2...@gmail.com

unread,
Feb 11, 2018, 3:47:02 PM2/11/18
to
> Varrebbe la pena imparare come connettersi ad un db remoto ed importare i dati da esso. Non e` cosi` complicato.


Quindi cosa mi consigliate per imparare a connettermi a un db remoto? Che guide/manuali posso leggere?
Non saprei proprio da dove iniziare.

Grazie!

Daniele

unread,
Feb 12, 2018, 6:08:00 AM2/12/18
to
Ciao,

>> Varrebbe la pena imparare come connettersi ad un db remoto ed importare i
>> dati da esso. Non e` cosi` complicato.

> Quindi cosa mi consigliate per imparare a connettermi a un db remoto? Che
> guide/manuali posso leggere?
Te lo hanno appena detto ....
Se usi firedac e un db remoto gestito da firedac (per esempio firebird) devi
configurare correttamente la connessione al db.
Quello di cui hai bisogno e'
indirizzo ip della server
porta di accesso che DEVE essere aperta anche sul firewall
percorso + file del db
credenziali di accesso

Quando hai tutto cio', configura la connessione di FD e fai il test !!

Attento che se sviluppi sullo stesso pc in rete i test non funzionano

> Non saprei proprio da dove iniziare.
Prova a partire da qui!!!

Ciao

Daniele

Alessandro B.

unread,
Feb 12, 2018, 8:20:51 AM2/12/18
to
Ciao,
non ci sono differenze sostanziali nel connettersi a un DB locale rispetto a uno remoto, tranne la velocità di risposta. Le credenziali e i parametri sono gli stessi (hai bisogno ovviamente dell'indirizzo IP del server)

Ci sono differenze di configurazione nel server / firewall che deve consentire la connessione da remoto (alcuni provider non la danno neppure come possibile...)

Devi però iniziare a "pensare" in modo diverso: quando fai una elaborazione su un sistema remoto devi pensare che il fetch dei record (caricamento di un recordset in memoria) è molto dispendioso in termini di tempo.

Quindi devi fare di tutto per evitare questa situazione.
La cosa migliore è lavorare con comandi che non prevedano il "ciclo" su tutti i record di una query.

Ovviamente ci sono varie strategie al riguardo, tra cui inserire un campo che contenga la marcatura temporale dell'ultima modifica fatta su un record

Devi pensare anche a come gestire i record cancellati (che ovviamente non ci sono più nel database di origine...) e vanno rimossi in quello da sincronizzare.

Se poi sei in un progetto professionale, potresti anche utilizzare delle funzioni disponibili in alcuni motori database che gestiscono direttamente sincronizzazioni dati.
Ad esempio SQL Server (non la versione Express...), oppure MariaDB / MySql

jax2...@gmail.com

unread,
Feb 12, 2018, 2:45:42 PM2/12/18
to
Il giorno lunedì 12 febbraio 2018 12:08:00 UTC+1, Daniele ha scritto:
> Ciao,
>
> >> Varrebbe la pena imparare come connettersi ad un db remoto ed importare i
> >> dati da esso. Non e` cosi` complicato.
>
> > Quindi cosa mi consigliate per imparare a connettermi a un db remoto? Che
> > guide/manuali posso leggere?
> Te lo hanno appena detto ....
> Se usi firedac e un db remoto gestito da firedac (per esempio firebird) devi
> configurare correttamente la connessione al db.
> Quello di cui hai bisogno e'
> indirizzo ip della server
> porta di accesso che DEVE essere aperta anche sul firewall
> percorso + file del db
> credenziali di accesso


Ciao Daniele,

ho capito la logica sottostante ma avrei bisogno di leggere qualcosa a riguardo (demo, manuali, ecc.), perché non saprei proprio che codice scrivere. Inoltre sul server, a parte aprire le porte, devo fare qualcos'altro o è sufficiente salvare solo il database?
Per fare tutto ciò, posso anche utilizzare i servizi di hosting gratuiti?

Sul web ho visto che ci sono delle guide per l'utilizzo dei componenti DataSnap con i server Rest. Potrebbero fare al caso mio? Se sì, come si utilizzano?

Grazie!


p.s.: sono riuscito a risolvere il mio problema! Il codice era corretto, bisognava solo cambiare una proprietà del componente TIdFtp: da ASCII a Binario. I tempi della procedura sono anche abbastanza veloci, considerando che il database pesa circa 500Kb.

Message has been deleted

jax2...@gmail.com

unread,
Feb 12, 2018, 3:53:08 PM2/12/18
to
@ Alessandro B.

>>quando fai una elaborazione su un sistema remoto devi pensare che il fetch dei record (caricamento di un recordset in memoria) è molto dispendioso in termini di tempo.
Quindi devi fare di tutto per evitare questa situazione.
La cosa migliore è lavorare con comandi che non prevedano il "ciclo" su tutti i record di una query.
Ovviamente ci sono varie strategie al riguardo, tra cui inserire un campo che contenga la marcatura temporale dell'ultima modifica fatta su un record
Devi pensare anche a come gestire i record cancellati (che ovviamente non ci sono più nel database di origine...) e vanno rimossi in quello da sincronizzare


Ciao Alessandro,
ci sono degli esempi di codice da poter studiare?
Con i servizi di hosting gratuito si può realizzare?

Grazie.
Message has been deleted

a.laf...@gmail.com

unread,
Feb 12, 2018, 6:36:30 PM2/12/18
to
On Monday, 12 February 2018 13:20:51 UTC, Alessandro B. wrote:

[...]
> Devi però iniziare a "pensare" in modo diverso: quando fai una elaborazione su un sistema remoto devi pensare che il fetch dei record (caricamento di un recordset in memoria) è molto dispendioso in termini di tempo.

E` sicuramente meno dispendioso che estrarre i dati, salvarli su file, metterli a disposizione su un server ftp, scaricare il file ed importarlo nel sistema.

Daniele

unread,
Feb 13, 2018, 3:50:04 AM2/13/18
to
Ciao,

> ho capito la logica sottostante ma avrei bisogno di leggere qualcosa a
> riguardo (demo, manuali, ecc.),
> perché non saprei proprio che codice scrivere. Inoltre sul server, a parte
> aprire le porte, devo fare
> qualcos'altro o è sufficiente salvare solo il database?
> Per fare tutto ciò, posso anche utilizzare i servizi di hosting gratuiti?

Ma sei riuscito a connetterti al db remoto ?
Per le mie limitate capacita' tecniche posso accompagnarti fino alla
connessione (e al limite alla lettura del db).
Per la sincronizzazione ..... non sono la persona giusta !!

> p.s.: sono riuscito a risolvere il mio problema! Il codice era corretto,
> bisognava solo cambiare
> una proprietà del componente TIdFtp: da ASCII a Binario. I tempi della
> procedura sono
> anche abbastanza veloci, considerando che il database pesa circa 500Kb.
Non sembra un grande db (mezzo mega!!)
Il db su cui lavoro io e' composto da (circa) 700 tabelle e pesa 5 gb .....
e non e' tra i piu' imponenti !!!

Spero tu riesca a risolvere in breve tempo !!!

Ciao

Daniele

Alessandro B.

unread,
Feb 13, 2018, 11:17:10 AM2/13/18
to
Confermo che questa è proprio l'operazione che sconsiglio di fare.
Estrarre, fare upload ftp, scaricare da ftp, ricaricare, ...

Io suggerivo: se in DB con 100.000 record e dall'ultima verifica ne sono stati cambiati 100, perché trasferire tutti i 100.000 record?

Non è una cosa semplice da fare, ma aggiornare solo i 100 record modificati è molto più efficente

Alessandro B.

unread,
Feb 13, 2018, 12:06:46 PM2/13/18
to
> ci sono degli esempi di codice da poter studiare?
Non saprei suggerirti degli esempi di codice.
Io sono partito da una analisi per la sincronizzazione di un database per un B2B, che in realtà mi ha dato solo una struttura di un database diverso da quello che utilizzo nel mio software.

L'unica indicazione era quella di distinguere i record modificati dai record cancellati e sono partito da questo.

Da li ho predisposto un paio di campi in ogni tabella da sincronizzare, uno con il timestamp dell'ora dell'ultima modifica, un altro con un flag di record sincronizzato

Una semplice query sul sistema mi consentiva di sapere quali erano i record da sincronizzare (flag sincronizzato)

Il timestamp mi da la possibilità di aggiornare per primi i record che sono stati modificati da più tempo e come opzione aggiuntiva di poter eseguire il riaggiornamento a partire da una data/ora ben precisa.

Per i cancellati (che non ho più fisicamente nel mio database) ho invece utilizzato una tabella secondaria con ID e nome tabella, sempre da utilizzare per la sincronizzazione

> Con i servizi di hosting gratuito si può realizzare?
Sinceramente non saprei.
Per i servizi web utilizzo dei miei server e mai servizi in hosting


a.laf...@gmail.com

unread,
Feb 14, 2018, 2:28:44 AM2/14/18
to
Eh e chi dice che si debba scaricare tutto?

Alberto Salvati

unread,
Feb 14, 2018, 8:43:48 AM2/14/18
to
Intanto, ti suggerisco quanto meno di *valutare* l'effort e preparare una bozza di risk assestment per un eventuale porting della tua applicazione delphi su altro: delphi "fu"...


> E se devi fare una applicazione che possa girare anche su IOS o MAC?

Quello è un tema spinoso.
Avere 2 app totalmente diverse ovviamente (ma per per tutti) oltre a non essere poco conveniente avrebbe poco senso.
Quindi, si, avere un strumento che vada "abbastanza" bene per entrambi potrebbe essere una scelta furba, a patto che lo strumento *funzioni*, mantenga nei limiti del buon senso ciò che promette e soprauttto non ti faccia rimpiangere di non aver optato per avere 2 app diverse...
In un caso del genere, *valuterei* sicuramente xamarin ma non delphi.


>
> Personalmente ho una APP che ho scritto in Delphi (Android) nella quale ho
> riutilizzato circa 500.000 linee di codice... tratte da uno dei miei progetti
> a cui lavoro da anni che ha circa 2.100.000 linee di codice

Queste 500.000 righe cosa fanno?

>
> Quanto tempo avrei impiegato a riscrivere quelle righe?

Rilancio:

1) hai fatto un copia&incolla del codice o hai dovuto modificarlo?

2) Quanto tempo hai impiegato per "infilare" il tuo codice dentro la app?

3) Quanto tempo hai impiegato, in totale, per sviluppare la tua app in delphi?

4) Quanto è stabile la tua app scritta in delphi?

5) Sei certo che, utilizzando uno strumento diverso, avresti avuto comunque necessità delle 500.000 righe di codice che ti sei portato dietro?

6) hai messo in conto il know-how che NON hai acquisito?


> N.B. Ovviamente questo è il mio parere personale

Tranquillo! :-D

A.

a.laf...@gmail.com

unread,
Feb 15, 2018, 7:57:10 AM2/15/18
to
On Sunday, 11 February 2018 15:10:18 UTC, Alessandro B. wrote:

[...]
> Per ultimo, riguardo al consiglio di connetterti al DB da remoto avrei una critica: di solito quando utilizzi un DB remoto viene impostato nel server che questo possa essere utilizzato solo da applicazioni locali (per ragioni di sicurezza).

Si`, e` probabile che il db in questione sia blindato per cui non accessibile direttamente (l'OP parla di db "su un server" senza aggiungere altro). Se e` quello il caso, "consumare" un'API REST di solito e` cosa banale da fare.

Alessandro B.

unread,
Feb 16, 2018, 5:03:12 AM2/16/18
to
> Si`, e` probabile che il db in questione sia blindato per cui non accessibile direttamente (l'OP parla di db "su un server" senza aggiungere altro). Se e` quello il caso, "consumare" un'API REST di solito e` cosa banale da fare.

Confermo che era questo che intendevo

Alessandro B.

unread,
Feb 16, 2018, 5:30:15 AM2/16/18
to
Scusa il ritardo per la risposta... l'influenza ha colpito...

Premetto che l'APP è una integrazione di un software gestionale.
Si tratta di una applicazione che si collega con tecnologia Snap ad un servizio sempre scritto in Delphi

> Queste 500.000 righe cosa fanno?
>
Credo che ogni programmatore abbia bisogno di una serie di routine che se non ha si deve scrivere nell'ambiente in cui lavora.

Faccio solo un paio di esempi: ci sono circa 100.000 righe dedicate alla sola virtualizzazione di accesso ai dati.

Consentono di virtualizzare l'accesso ai DB utilizzando (a seconda dei parametri) Firedac, DbExpress, Ado e ... BDE (si ancora lui), di accedere a MsSql, Firebird, Interbase, SqLite, ..., di impostare filtri in modo trasparente, di gestire la struttura e l'aggiornamento dinamico delle tabelle, ...

Nell'app ho un database in SqLite, con una serie di tabelle che hanno la stessa struttura di quelle del gestionale

Altrettante sono dedicate a gestione di stringhe, liste, criptazione dati, conversioni di tipo, utilizzo immagini, controllo validazione e gestione licenza cliente, messaggi, ...

Molte righe sono righe proprie del gestionale
In alcuni casi mi è più conveniente eseguire una richiesta Snap e avere la risposta dal server
In altri casi riutilizzo la logica di programmazione del gestionale direttamente nell'App

Il vantaggio al momento è che quando modifico la logica del gestionale e ricompilo sia il gestionale che l'App ho in realtà aggiornato entrambe


> Rilancio:
>
> 1) hai fatto un copia&incolla del codice o hai dovuto modificarlo?
>
Non ho fatto copia e incolla: ho modificato le unit del sorgente con compilazione condizionale dove necessario.
Compilano al momento in RADStudio 10.2 e precedenti, tutti i vari XE*, Delphi 2007, Delphi 7 e Delphi 5 (si ho ancora un progetto con quel vecchio sistema)
Compilano sia per VLC che FMX, sia per Windows, Android che MAC / IOS

Il lavoro di adeguamento ha comportato parecchio tempo, ma era comunque necessario per il porting di applicazioni windows ai sistemi più recenti

> 2) Quanto tempo hai impiegato per "infilare" il tuo codice dentro la app?
>
L'app è stata scritta in un paio di settimane, con circa 4000 righe di codice

> 3) Quanto tempo hai impiegato, in totale, per sviluppare la tua app in delphi?
>
un paio di settimane per l'app, un paio per la gestione del collegamento Snap

> 4) Quanto è stabile la tua app scritta in delphi?
>
Non ho al momento segnalazioni di problemi con l'App
Ne ho al contrario qualche volta con il servizio snap che gira sul server, ma credo dipenda dalle altre applicazioni che stanno girando nel server

> 5) Sei certo che, utilizzando uno strumento diverso, avresti avuto comunque necessità delle 500.000 righe di codice che ti sei portato dietro?
>
No. probabilmente non tutte... ma forse almeno una parte

> 6) hai messo in conto il know-how che NON hai acquisito?
>
Questo è il mio cruccio maggiore

Alberto Salvati

unread,
Feb 16, 2018, 6:05:51 AM2/16/18
to
> Scusa il ritardo per la risposta... l'influenza ha colpito...

..io l'ho beccata a cavallo di natale e capodanno che ero giù.. :-((

> Faccio solo un paio di esempi: ci sono circa 100.000 righe dedicate alla sola > virtualizzazione di accesso ai dati.
>
> Consentono di virtualizzare l'accesso ai DB utilizzando (a seconda dei
>parametri) Firedac, DbExpress, Ado e ... BDE (si ancora lui), di accedere a
>MsSql, Firebird, Interbase, SqLite, ..., di impostare filtri in modo
> trasparente

Magari faccio la predica ad un convertito..
Questo in molte "cose" che non siano delphi è integrato.
Vedi EF (.net) o quanto basato su JPA per Java.
Certo, all'inizio occorre studiare, ma la curva di apprendimento non è particolarmente ripida.
Questo però si basa sul presupposto che le tue tabelle sia dati e non metadati che descrivono entità, nel quale caso non ho idea se tali strumenti possano essere comunque utili..


> In alcuni casi mi è più conveniente eseguire una richiesta Snap e avere la
> risposta dal server
> In altri casi riutilizzo la logica di programmazione del gestionale
> direttamente nell'App
>
> Il vantaggio al momento è che quando modifico la logica del gestionale e
> ricompilo sia il gestionale che l'App ho in realtà aggiornato entrambe

Questo è sicuramente un vantaggio. :-)


> compilazione condizionale dove necessario.
> Compilano al momento in RADStudio 10.2 e precedenti, tutti i vari XE*, Delphi
> 2007, Delphi 7 e Delphi 5 (si ho ancora un progetto con quel vecchio sistema)
> Compilano sia per VLC che FMX, sia per Windows, Android che MAC / IOS

Un azienda con la quale entrai in contatto anni fa aveva un software il cui codice (sempre delphi) facendo pesante uso di direttive di compilazione.
Piangevano...




> > 6) hai messo in conto il know-how che NON hai acquisito?
> >
> Questo è il mio cruccio maggiore

Il problema è sempre legato al rapporto tra il tempo disponibile e quello da dedicare a mutuo&pagnotta.


A.


0 new messages