Mentre cerco notizie sulla gestione di un DB-sqlite3, partendo dalla sua creazione, cerco di appuntare sulla carta i passi da inserire all'interno di un programma. Una delle prime curiosità che ho cercato di esaudire é quella di dovere gestire un DB già strutturato o di strutturarlo nel programma stesso (logicamente solo la prima volta). Ho visto, attraverso i post relativi ed attraverso programmini di prova messi a disposizione dai più esperti che é possibile creare un DB durante l'esecuzione del codice gambas e questo mi fa molto piacere (penso che knoda non me ne vorrà). Certo un programma che legge e aggiorna una o più tabelle di un DB predefinito con Knoda o con altro strunmento compatiubile con sqlite3 risulta più veloce da mettere a punto, ma non mi permetterebbe di fare esperienza anche in fase di creazione. ;-)
Nei post che ho guardato ho fatto attenzione all'individuazione del DB in HD e non ho trovato descritto in maniera elementare la dichiarazione del path completo fino alla directory che contiene il DB; esempiio:
' Gambas class file
PUBLIC $hconn1 AS Connection
PUBLIC $hconn2 AS Connection
PUBLIC SUB Button1_Click()
DIM $hConn AS Connection
DIM sName AS String ' nome del database
$hConn = NEW Connection ' inizializza una nuova connessione
sName = "esempio.db" ' imposto i parametri di connessione
WITH $hConn
.Type = "sqlite3" 'tipo di database
.Host = User.Home percorso del database °°° ??? °°°
END WITH
..........
END
Mi sono permesso di ripotrtare qualche riga di codica dal programmino di prova che molto cortesemente mi ha fornito fsurfing, e spero di non provocare il suo disappunto per questo, allo scopo di soffermarmi sulla riga ".Host" della funzione Widh. Infatti quando leggo
non capisco in quale directory sia ubicato il DB, o perlomeno, penso che sia nella directoy home dell'utente.
Supponiamo invece che il DB sia in una directory diversa dalla Home_user; per Es.:
home -> Utente_x -> gambas -> progetti -> progetto1 -> esempio.db
Potrebbe inoltre il DB trovarsi nella stessa directory di ProVaGambas (il programma che dovrà gestirlo) oppure essere in una directory diversa.
Ecco, restando a quello che ho capito, io scriverei:
.Host = home.Utente_x.gambas.progetti.progetto1
:uhm:
Non é che non mi fidi di me stesso, ma non mi pare che somigli all'esempio di partenza di fsurfing, nemmeno nella sua parte iniziale.
Dico bene?
:ciao:
leo72 ha scritto:
Oppure la cosa più semplice è mettere il DB nella cartella dove risiede il programma ed usare come indirizzo .host = Application.Path.
Ho letto solo oggi, a fine prova, il tuo consilgio, ma farò un'ulteriore prova per la messa punto pratico-logica di questo primo approccio di programma.
Ecco quello che sono riuscito a fare:
PUBLIC DB_Connection AS Connection
PUBLIC SUB _new()
END
PUBLIC SUB Form_Open()
DIM DB_Connection AS NEW Connection 'inizializza la nuova connessione
DIM Esito AS Result
DIM DBname AS String 'Nome del Database
DIM DB_path AS String 'Percorso di ricerca del Database ContabFam.db
DBname = "Archivio.db" 'imposto i parametri di connessione
DB_path = User.Home & "/Gambas/Gambas_Progetti/Progetto1/Proget1_DB"
WITH DB_Connection
.Type = "sqlite3"
.Host = DB_path
.Login = ""
.Password = ""
END WITH
DB_Connection.Open 'Tento l'apertura del DB, se presente
IF NOT DB_Connection.Databases.Exist(DBname) THEN 'verifica che il DB non esista
SELECT Message.ERROR("Attenzione! -> archivio '" & DBname & "' NON TROVATO", "Creare DB ex novo", "Uscita dal programma")
CASE 1
DB_Connection.Databases.Add(DBname) 'crea il DB
DB_Connection.CLOSE 'chiude il DB
Message.Info("DB '" & DBname & "' Creato - FINE PROVA ")
CASE 2
Message.Info("hai premuto il pulsante: Uscita dal programma - FINE PROVA")
END SELECT
QUIT 'Esce dal programma
ELSE
Message.Info("Il DB" & DBname & "ESISTE GIÀ - FINE PROVA")
DB_Connection.CLOSE 'chiude il DB
QUIT 'Esce dal programma
ENDIF
END
:-D
Ho faticato un pò per cominciare ad assorbire la nuova mentalità, ma penso di essere sulla buona strada.
Nella verifica della presenza o meno del DB, dopo la " DB_Connection.Open", ho preferito gestitre come eccezionale la condizione di "NOT Exist", in quanto, dopo averlo creato la prima volta per tutte le altre innumerevoli volte di utilizzo, me lo ritroverò bello e presente; pertanto probabilmente l'esecuzione é leggermente più veloce e la lettura del codice diventa più scorrevole ai miei occhi.
Ora riprovo modificando il path e se tutto si rende autodinamico, come spero, posso benissimo passare alla definizione della prima tabella.
Grazie per la collaborazione e, se non ci dovessimo risentire prima del 25-dic.,
Buooon Naataalee a tutti!!! :pint:
:ciao: :ciao:
La prova della creazione di una tabella dentro il DB appena nato funzionerebbe se non avessi bisogno di definire una primary key distribuita su tre campi. Leggendo però il "A Beginner's Guide to Gambas" apprendo quanto segue: PrimaryKey will return or set the primary key of the table.The primary key is a string array containing the name of each primary key field. System will return a TRUE value if the database is a system database. Type returns or sets the type of a table. This property is unique to MySQL and is only used with MySQL databases.
:uhm:
Per maggiore chiarezza: ho eseguioto i seguenti passi:
DIM sql AS String
DIM sqltable AS Result
................
WITH
DB_Connection
.Name = DBname
.OPEN 'Riapro il DB
END WITH
sql = "CREATE TABLE 'TabPro1' ("
sql = sql & " 'Datagg' CHAR(8) DEFAULT NULL PRIMARY KEY, "
SQL = SQL & " 'NuProgg' INTEGER PRIMARY KEY,"
SQL = SQL & " 'CoVogg' CHAR(8) DEFAULT not NULL PRIMARY KEY,"
SQL = SQL & " 'Descrgg' VARCHAR(100) DEFAULT NULL,"
SQL = SQL & " 'Impgg' FLOAT DEFAULT not NULL);"
sqltable = DB_Connection.Exec(sql)
L'esecuzione mi ha fornito il seguente errore:
Query failed. SQL error or m issing databse
Ho provato a limitare la primary key ad un solo elemento di tabella e la tabella é stata creata con successo.
La mia soluzione pratica sarebbe quella di creare un campo primary key comprendente tutti i campi assegnati come primary key nell'esempio appena riportato, però penso che avrei difficoltà successivamente nelle ricerche parziali.
Penso tuttavia che dalla stesura della guida Gambas ad oggi, anche Sqlite sia cresciuto, per cui potrebbe esere che si possa gestire ormai una primary key costituita dal concatenamento dei campi che la compongono, per cui esiste già una soluzione che nei post del Forum non ho trovato (o non sono stato capace di trovare). :-(
Spero tanto che la Vostra esperienza conoscitiva mi possa illuminare. Grazie ancora e rinnovati Auguri di Buon Natale! :ciao: :ciao:
md9327 ha scritto:
... credo tu debba partire dai principi base della sintassi sql (nella fattispecie specifiche SQL-92), e poi andare ad analizzare le particolari applicazioni di questa sintassi da parte dei vari dbms.
Debbo essere sincero: non ho guardato subito le specifiche SQL-92, perché prima ho voluto fare ancora una prova: ho guardato con molta attenzione il non facile schema grafico-intuitivo presente in "www.sqlite.org" per la costruzione del comando SQL "CREATE TABLE" ed ho tracsritto su carta i segmenti dell'istruzione necessaria per la creazione della mia prima tabella. Ho così, passo dopo passo, verificato la sintassi scritta nel programma ed ho ottenuto alla fine il seguente codice gambas:
DIM sql AS String 'serve per eseguire i comandi sul DB
DIM sqltable AS Result
................
sql = "CREATE TABLE 'Movimgg' ("
sql = sql & " 'DtMovvgg' CHAR(8),"
SQL = SQL & " 'NuProMovvgg' INTEGER,"
SQL = SQL & " 'CoVocMovvgg' CHAR(8),"
SQL = SQL & " 'DescrMovvgg' VARCHAR(100) DEFAULT NULL,"
SQL = SQL & " 'MValMovvgg' CHAR(1) DEFAULT NULL,"
SQL = SQL & " 'ImpMovvgg' FLOAT DEFAULT NULL,"
SQL = SQL & " 'BenefMovvgg' CHAR(1) DEFAULT NULL,"
SQL = SQL & " PRIMARY KEY ("
SQL = SQL & " 'DtMovvgg'," 'primo campo della primary key
SQL = SQL & " 'NuProMovvgg'," 'secondo campo della primary key"
SQL = SQL & " 'CoVocMovvgg'" 'terzo campo della primary key
SQL = SQL & " ));"
sqltable = DB_Connection.Exec(sql)
Message.Info("Tabella 'movimgg' Creata - FINE PROVA ")
Ho mandato in seecuzione il programma e finalmente ho potuto leggere il mio Messaggio di "Fine Prova", Non ho potuto fare a meno di :evviva:
E visto che siamo arrivati alla vigilia di Natale, per me é stato un grandissimo regalo di "Babbo Natale Gambas+SQLite3".
Ho voluto riportare il codice solamente perché possa essere d'aiuto a chi dovesse avere la mia stessa necessità ed, utilizzando i post come documentazione di supporto, possa arrivare molto comodamente alla soluzione.
Dimenticavo: ho aperto il DB con Knoda ed ho potuto riscontrare l'effettiva esistenza della tabella con tutti i campi, però devo ancora approfondirne la conoscenza per potere ottenere la vista della sua struttura.
Grazie per il sostegno. Buon Natale a tutti.
:pint: :ciao: :ciao:
1)
scusate se mi intrometto.... ma questo codice:
CASE 1
DIM CreDB AS NEW Class
è errato. Come riporta la documentazione di Gambas:
All DIM declarations must be in the FUNCTION or SUB before the first executable command.
Non puoi dichiarare una variabile/oggetto/altro in mezzo alle istruzioni ed ai comandi: lo devi fare tutto in cima alla procedura/funzione, prima della prima istruzione.
Probabilmente la DIM a cui si riferisce Gambas è proprio quella.
2)
Per chiudere un programma si dovrebbe usare l'evento Close() affinché Gambas avvii la gestione della chiusura tramite la Sub Form_Close(), dove puoi mettere del codice tuo. Per invocarlo basta invocare ME.Close da un qualsiasi punto del form/class che si vuole chiudere.
Un sistema molto semplice per verificare che una tabella contenga dati e/o alcuni tipi di dati è di utilizzare la proprietà Available dell'oggetto Result, che serve proprio a verificare se il record è esistente. Il tuo test potrebbe essere riscritto così:
NomeRec = DB_Connection.Edit("GGAperte")
IF NOT NomeRec.Available THEN
Message.Warning("Tabella vuota")
ELSE
NopmeTab alla Tabella GGAperte in modalità lettura record
$DataCont = NomeRec!DtCoGGAp
ENDIF
md9327 ha scritto:
Riguardo le funzionalità EOF/BOF, l'oggetto Result ti offre metodi alternativi; ...................................
Il controllo del metodo Result.Count ti ritorna l'esatto numero di record caricati dal database.
leo72 ha scritto:
Un sistema molto semplice per verificare che una tabella contenga dati e/o alcuni tipi di dati è di utilizzare la proprietà Available dell'oggetto Result, che serve proprio a verificare se il record è esistente. Il tuo test potrebbe essere riscritto così:
NomeRec = DB_Connection.Edit("GGAperte")
IF NOT NomeRec.Available THEN
Message.Warning("Tabella vuota")
ELSE
NopmeTab alla Tabella GGAperte in modalità lettura record
$DataCont = NomeRec!DtCoGGAp
ENDIF
Vi ringrazio tantissimo per i vostri consigli. Ho capito che essendo Gambas assai malleabile nell'uso di istruzioni che permettonio di arrivare allo stesso risultato, basta applicare al proprio programma quell'insieme di codice più congeniale al modo di scrivere e del programmatore. Ho letto il suggerimento di leo72 dopo avere ragionato sul suggerimento di md9327 ed hoadottato la seguente soluzione:
DB_Connection.Begin
NomeRec = DB_Connection.edit("GGAperte")
n_NumElem = NomeRec.Count 'estrae il n° di record presenti nella tabella GGAperte
'Message.Info("La Tabella 'GGAperte' contiene n°" & n_NumElem & " righe")
IF n_NumElem = 0 THEN
Message.Info("Tabella 'GGAperte' --> V U O T A" )
ELSE
$DataCont = NomeRec!DtCoGGAp 'carico in memoria il contenuto
ENDIF
:-D
:ciao: :ciao:
Ricorda, Gambas è un linguaggio in cui non esiste un solo modo per fare una cosa. Ne esistono tanti, ognuno sceglie quello che più gli piace o che conosce.
Il tuo controllo potrebbe anche diventare:
IF NomeRec.Count = 0 THEN
Message.Info("Tabella 'GGAperte' --> V U O T A" )
ELSE
$DataCont = NomeRec!DtCoGGAp carico in memoria il contenuto
ENDIF
senza dover assegnare il valore di NomeRec.Count ad una variabile temporanea.
Questo per confermare quanto da me detto sopra.