Operazioni base

Per poter eseguire comandi su un server Konga, si deve instanziare ed usare un oggetto di classe Client.

Classe Client

class kongalib.Client

La classe Client permette di connettersi ad un server Konga e di eseguire comandi sullo stesso.

Molti dei metodi di questa classe possono eseguire operazioni sia in maniera sincrona (bloccante) che asincrona tramite l’uso di una callback. Nel caso un metodo sia eseguito in modo asincrono, viene sempre restituito immediatamente un oggetto di classe Deferred, e la callback viene eseguita a tempo debito in un thread separato.

Nota

Nelle chiamate asincrone spesso è possibile specificare una callback di progress e una di error. La progress deve essere nella forma progress(type, completeness, state, partial, userdata); i parametri interessanti di questa callback sono completeness (percentuale di completamento, ossia un numero che varia da 0.0 a 100.0; se -1.0 indica una percentuale di completamento indefinita) e state (stringa che specifica l’eventuale stato corrente dell’operazione). userdata è un parametro aggiuntivo che viene normalmente passato alla chiamata asincrona dall’utente per tenere traccia di un eventuale stato. La error deve essere nella forma error(errno, errstr, userdata); fare riferimento ai codici di errore per il significato dei parametri errno e del corrispettivo errstr.

Oggetti di classe Client possono essere usati come contesti per il costrutto with: all’ingresso del blocco verrà iniziata una transazione, mentre in uscita verrà eseguita una commit o una rollback della stessa a seconda che ci sia stata o meno un’eccezione all’interno del blocco di istruzioni.

authenticate(username, password, success=None, error=None, progress=None, userdata=None, timeout=180000)

Effettua un accesso al database attivo sulla connessione corrente, identificando l’utente tramite i parametri username e password. Se success è None, la chiamata è bloccante e restituisce un dict con informazioni dettagliate sull’utente autenticato, oppure viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(info, userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con le informazioni sull’utente ed il parametro userdata.

backup_database(password, backup_name, driver, name, auto=True, overwrite=False, success=None, error=None, progress=None, userdata=None, timeout=180000)

Esegue un backup del database specificato sul server attualmente connesso. Se auto è False, è necessario specificare un nome per il backup tramite backup_name, altrimenti il backup viene considerato automatico ed un nome univoco è assegnato dal server. Se overwrite è False ed un backup con lo stesso nome esiste già sul server, non sarà possibile eseguire il backup. Se success è None, la chiamata è bloccante e viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con il parametro userdata.

Avvertimento

E” necessaria la password del server per poter eseguire questa operazione.

begin_transaction(pause_indexing=False, deferred=False)

Inizia una transazione sul database attivo nella connessione corrente. Se pause_indexing è True, l’indicizzazione del database è disabilitata sul server. In caso di errore viene lanciata l’eccezione Error.

close_database(backup=False, success=None, error=None, progress=None, userdata=None, timeout=180000)

Chiude il database attivo sulla connessione corrente. Se success è None, la chiamata è bloccante e viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con il parametro userdata.

Nota

Se backup è True, il server esegue un backup automatico del database prima di chiuderlo.

code_exists(tablename, code, code_azienda, num_esercizio, extra_where=None)

Controlla l’esistenza del codice code nella tabella tablename per l’azienda e l’esercizio specificati in code_azienda e num_esercizio.

commit_transaction(resume_indexing=False)

Esegue una COMMIT della transazione sul database attivo nella connessione corrente. Se resume_indexing è True, l’indicizzazione del database è abilitata sul server. In caso di errore viene lanciata l’eccezione Error.

connect(server=None, host=None, port=0, options=None, timeout=30000, success=None, error=None, progress=None, userdata=None)

Tenta una connessione ad un server Konga. Il server a cui ci si vuole connettere può essere specificato in due modi: tramite i parametri host e port, oppure tramite un dict server che deve contenere almeno le chiavi host e port. Alternativamente, se server è una stringa e host non è specificato, viene assunta come host. Se host include una specifica di porta e port è 0, port viene ottenuta dalla specifica contenuta nella stringa di host. Se success è None, la funzione è bloccante; su errore o scaduto il timeout una eccezione di tipo Error è lanciata, altrimenti viene restituito un dict con informazioni sulla connessione appena stabilita. Se success è una funzione nella forma success(info, userdata) allora connect restituisce immediatamente un oggetto Deferred e la chiamata viene eseguita in modo asincrono; la callback success verrà invocata con le informazioni sulla connessione e userdata se e quando la connessione viene stabilita.

create_database(password, driver, name, desc='', success=None, error=None, progress=None, userdata=None, timeout=180000)

Crea un nuovo database sul server attalmente connesso; il database avrà nome name e descrizione desc. Se success è None la chiamata è bloccante e se il database viene creato con successo viene restituito l’UUID del nuovo database; se si verifica un errore viene lanciata l’eccezione Error. Se success è una funzione nella forma success(databases, userdata), create_database restituisce immediatamente un oggetto Deferred e la chiamata viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con la lista dei database ed il parametro userdata.

Avvertimento

E” necessaria la password del server per poter eseguire questa operazione.

delete_backup(password, backup_name, success=None, error=None, progress=None, userdata=None, timeout=180000)

Cancella il backup identificato da backup_name dal server connesso. Se success è None, la chiamata è bloccante e viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con il parametro userdata.

Avvertimento

E” necessaria la password del server per poter eseguire questa operazione.

delete_database(password, driver, name, success=None, error=None, progress=None, userdata=None, timeout=180000)

Cancella il database specificato. Se success è None, la chiamata è bloccante e viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con il parametro userdata.

Avvertimento

E” necessaria la password del server per poter eseguire questa operazione.

delete_record(tablename, code=None, id=None, code_azienda=None, num_esercizio=None, log=None, success=None, error=None, progress=None)

Cancella un record dalla tabella tablename. Il record può essere identificato in due modi: o tramite il solo id, oppure tramite la specifica dei parametri code, code_azienda e num_esercizio. Se success è None la chiamata è bloccante, e in caso di errore verrà lanciata un’eccezione di classe Error o ErrorList. Se success è una funzione nella forma success(), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito. In modalità asincrona se log è un oggetto di classe OperationLog, esso riceverà ogni eventuale messaggio di log prodotto dal server durante l’aggiornamento.

disconnect()

Disconnette il server attualmente connesso, oppure non fa nulla se non si è al momento connessi.

Esegue una ricerca full-text sul database attivo sulla connessione corrente, limitando la ricerca di text a limit risultati. Se success è None, la chiamata è bloccante e restituisce una lista di risultati, dove ogni risultato è dict con almeno le chiavi score, tablename, id e display; in caso di errore viene lanciata l’eccezione Error. Se success è una funzione nella format success(hits, userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con i risultati della ricerca ed il parametro userdata.

get_connection_info()

Restituisce un dict con informazioni sulla connessione corrente, o None se non si è connessi.

get_data_dictionary(success=None, error=None, progress=None, userdata=None, timeout=180000)

Restituisce il dizionario dei dati disponibile sul server attualmente connesso, sotto forma di oggetto di classe kongalib.DataDictionary.

get_id()

Restituisce un ID numerico univoco assegnato dal server alla connessione con questo client, o 0 se non si è connessi.

get_record(tablename, code=None, id=None, field_names=None, row_extra_field_names=None, code_azienda=None, num_esercizio=None, mode=None, mask_binary=None, flags=287, success=None, error=None, progress=None)

Ottiene il record completo della tabella tablename, sotto forma di dict. Il record può essere identificato in due modi: o tramite il solo id, oppure tramite la specifica dei parametri code, code_azienda e num_esercizio. Se success è None la chiamata è bloccante, altrimenti verrà lanciata un’eccezione Error in caso di errore. Se success è una funzione nella forma success(data), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con i dati del record.

index_database(password, driver, name, reset=False, success=None, error=None, progress=None, userdata=None, timeout=180000)

Esegue una indicizzazione del database specificato sul server attualmente connesso. Se reset è False, l’indicizzazione è incrementale, ovvero l’indice viene modificato per tenere conto solo dei record inseriti, modificati o cancellati dall’ultima indicizzazione; se invece reset è True, l’indice viene prima cancellato e poi ricreato completamente. Se success è None, la chiamata è bloccante e viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con il parametro userdata.

Avvertimento

E” necessaria la password del server per poter eseguire questa operazione.

insert_record(tablename, data, code_azienda=None, num_esercizio=None, log=None, success=None, error=None, progress=None)

Inserisce un nuovo record nella tabella tablename. Il nuovo record, i cui dati sono passati nel dict data, sarà un record condiviso con tutte le aziende del database se code_azienda e num_esercizio sono None, altrimenti apparterrà solo all’azienda e all’esercizio specificati. Se success è None la chiamata è bloccante e ritornerà una tupla nella forma (id, code), dove id è l’ID univoco assegnato al record dal server, mentre code è il codice del record (che può essere diverso da quello passato in data se sono attivi i codici automatici per tablename); in caso di errore verrà lanciata un’eccezione di classe Error o ErrorList. Se success è una funzione nella forma success(id, code), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con l’ID ed il codice del nuovo record. In modalità asincrona se log è un oggetto di classe OperationLog, esso riceverà ogni eventuale messaggio di log prodotto dal server durante l’inserimento.

interrupt()

Interrompe tutte le operazioni al momento in esecuzione da parte di questo client.

list_backups(success=None, error=None, progress=None, userdata=None, timeout=180000)

Ottiene la lista dei backup disponibili sul server connesso. Se success è None, la chiamata è bloccante e restituisce una lista di backup; ogni backup è un dict che contiene almeno le chiavi backup_name, uuid, date e size; se si verifica un errore viene lanciata l’eccezione Error. Se success è una funzione nella forma success(backups, userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con la lista dei backup ed il parametro userdata.

list_databases(driver=None, quick=False, success=None, error=None, progress=None, userdata=None, timeout=180000)

Restituisce la lista dei database disponibili sul server corrente, appartenenti a tutti o ad uno specifico driver. La lista viene tornata sotto forma di dict, le cui chiavi sono i nomi dei driver e i valori le liste dei database appartenenti allo specifico driver. Ogni database nelle liste è un dict che contiene almeno le chiavi name, desc, uuid, created_ts e modified_ts. L’eccezione Error viene lanciata se si verifica un errore. Se success è una funzione nella forma success(databases, userdata), list_databases restituisce immediatamente un oggetto Deferred e la chiamata viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con la lista dei database ed il parametro userdata.

list_drivers(configured=True, success=None, error=None, progress=None, userdata=None, timeout=180000)

Restituisce la lista dei driver di database presenti sul server attualmente connesso, oppure lancia un’eccezione Error su errore. Ogni elemento della lista restituita è un dict che comprende la chiavi name, version e description. Se success è None la funzione è bloccante, altrimenti se è una funzione nella forma success(drivers, userdata), restituisce immediatamente un oggetto Deferred e la chiamata viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con la lista dei driver ed il parametro userdata. Se configured è False, tutti i driver installati sul server sono restituiti, altrimenti verranno restituite solo le informazioni sui driver configurati correttamente ed in esecuzione sul server.

list_servers(timeout=5000, port=0, success=None, progress=None, userdata=None)

Esegue una scansione della rete locale alla ricerca dei server Konga disponibili, attendendo al massimo timeout millisecondi per una risposta. port specifica la porta da cui far partire la scansione (default = 51967); sono controllate le successive 10 porte UDP con intervallo di 20 porte (quindi di default vengono scansionate le porte 51967, 51987, 52007, … 52147). Se success è None, la funzione è bloccante e scaduto il timeout restituisce una lista di dict, le cui chiavi principali sono host, port, name e description. Al contrario, se success è una funzione nella forma success(servers, userdata), list_servers restituisce immediatamente un oggetto Deferred e la chiamata viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con la lista dei risultati (come nel risultato del caso sincrono) ed il parametro userdata.

lock_resource(command, row_id=None)

Tenta di eseguire il blocco della risorsa identificata da command. Se row_id è diverso da None, è possibile eseguire il blocco di una singola riga di una tabella del database. Restituisce una tupla (result, owner_data), dove owner_data è un dict contenente informazioni sull’utente che detiene già il blocco della risorsa in caso fosse già bloccata, oppure lancia un’eccezione Error in caso di errore.

open_database(driver, name, success=None, error=None, progress=None, userdata=None, timeout=180000)

Apre un database rendendolo il database attivo per la connessione corrente. Se success è None, la chiamata è bloccante e viene tornato un dict con le informazioni sul database connesso, oppure viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(info, userdata), open_database restituisce immediatamente un oggetto Deferred e la chiamata viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con le informazioni sul database ed il parametro userdata.

optimize_database(password, driver, name, success=None, error=None, progress=None, userdata=None, timeout=180000)

Esegue una ottimizzazione del database specificato sul server attualmente connesso. Se success è None, la chiamata è bloccante e viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con il parametro userdata.

Avvertimento

E” necessaria la password del server per poter eseguire questa operazione.

query(query, native=False, full_column_names=False, collapse_blobs=False, success=None, error=None, progress=None, userdata=None, timeout=180000)

Esegue una query SQL sul database attivo nella connessione corrente. Se native è True, la query viene passata al driver del database senza essere interpretata, permettendo l’esecuzione di query native per l’RDBMS sottostante. Se success è None, la chiamata è bloccante e viene restituita una tupla (affected_rows, column_names, result_set); affected_rows è il numero di righe coinvolte nella query di UPDATE/DELETE, column_names è una lista di nomi di colonne per il result set, mentre result_set è una lista di righe risultati della query, dove ogni riga è una lista di valori corrispondenti alle colonne restituite in column_names. In caso di errore viene lanciata l’eccezione Error. Se success è una funzione nella forma success(affected_rows, column_names, result_set, userdata), query restituisce immediatamente un oggetto Deferred e la chiamata viene eseguita in modo asincrono.

Nota

Se full_column_names è False, column_names includerà i nomi delle colonne senza nome tabella, altrimenti saranno inclusi i nomi completi delle colonne. Se collapse_blobs è True, i dati di tipo BLOB binari verranno restituiti come [...].

repair_database(password, driver, name, output, success=None, error=None, progress=None, userdata=None, timeout=180000)

Prova a riparare il database danneggiato specificato, salvando il database recuperato in output. Se success è None, la chiamata è bloccante e viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(userdata), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con il parametro userdata.

Nota

Non tutti i driver di database supportano questa operazione, e il recupero del database potrebbe fallire in ogni caso.

Avvertimento

E” necessaria la password del server per poter eseguire questa operazione.

restore_database(password, backup_name, driver, name, change_uuid=True, overwrite=False, success=None, error=None, progress=None, userdata=None, timeout=180000)

Ripristina un database a partire da un backup effettuato in precedenza sul server connesso. Se overwrite è False ed esiste un database gestito da driver con lo stesso nome, la funzione riporterà errore. change_uuid specifica se cambiare l’UUID associato al database oppure se ripristinare quello originale; se si hanno database con lo stesso nome gestiti da driver diversi è opportuno che almeno l’UUID per essi sia diverso, altrimenti si può incorrere in problemi di aliasing.

Avvertimento

E” necessaria la password del server per poter eseguire questa operazione.

rollback_transaction(resume_indexing=False)

Esegue un ROLLBACK della transazione sul database attivo nella connessione corrente. Se resume_indexing è True, l’indicizzazione del database è abilitata sul server. In caso di errore viene lanciata l’eccezione Error.

select_data(tablename, fieldnamelist=None, where_expr=None, order_by=None, order_desc=False, offset=0, count=None, get_total=False, exist=None, success=None, error=None, progress=None)

Genera ed esegue una SELECT sul server per ottenere una lista di risultati, a partire dalla tabella tablename. fieldnamelist è una lista di nomi dei campi da ottenere; se un campo fk_X di tablename è una foreign key, si può accedere ai campi della tabella collegata Y specificando «fk_X.Campo_di_Y»; la JOIN corrispondente verrà generata e gestita automaticamente dal server. Analogamente, si possono creare catene di JOIN implicite facendo riferimenti multipli di campi foreign key, per esempio «fk_X.fk_Y.fk_Z.Campo_di_Z».

Se where_expr non è None, può essere il corpo di una espressione WHERE SQL, e può contenere riferimenti nella stessa forma di fieldnamelist, per esempio «(Campo_di_X = 1) AND (fk_X.Campo_di_Y > 5)».

order_by può essere un nome di campo per cui ordinare i risultati, dove order_desc specifica se ordinare in modo ascendente o discendente. offset e count permettono di restituire risultati solo a partire dal numero offset, e limitandosi a count risultati.

Se get_total è True, il valore di ritorno (o gli argomenti della callback success) sarà una tupla nella forma (result_set, total_rows, exist_results); total_rows sarà il numero totale di righe come se offset e limit non fossero stati specificati, mentre exist_results sarà un dict le cui chiavi saranno gli ID specificati nel parametro exist, e i valori saranno True o False a seconda che il corrispettivo ID sia presente nel database per la tabella tablename oppure no.

Se success è None la chiamata è bloccante e verrà restituito un risultato come descritto sopra, altrimenti verrà lanciata un’eccezione Error in caso di errore. Se success è una funzione nella forma success(result_set) oppure success(result_set, total_rows, exist_results) (a seconda del parametro get_total come descritto sopra), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito.

select_data_as_dict(tablename, fieldnamelist=None, where_expr=None, order_by=None, order_desc=False, offset=0, count=None, get_total=False, success=None, error=None, progress=None)

Esattamente come select_data(), ma restituisce il result_set come una lista di dict, anzichè una lista di liste.

unlock_resource(command, row_id=None)

Rilascia il blocco della risorsa identificata da tablename e row_id.

update_record(tablename, data, code=None, id=None, code_azienda=None, num_esercizio=None, log=None, success=None, error=None, progress=None)

Aggiorna un record esistente nella tabella tablename. Il record, i cui dati da aggiornare sono passati nel dict data, può essere identificato in due modi: o tramite il solo id, oppure tramite la specifica dei parametri code, code_azienda e num_esercizio. Se success è None la chiamata è bloccante, e in caso di errore verrà lanciata un’eccezione di classe Error o ErrorList. Se success è una funzione nella forma success(), la chiamata restituisce immediatamente un oggetto Deferred e l’operazione viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito. In modalità asincrona se log è un oggetto di classe OperationLog, esso riceverà ogni eventuale messaggio di log prodotto dal server durante l’aggiornamento.

upgrade_database(password, driver, name, success=None, error=None, progress=None, userdata=None, timeout=180000)

Aggiorna il database specificato all’ultima versione disponibile. Se success è None, la chiamata è bloccante e viene restituita una tupla (log, old_version, new_version), dove il log dell’operazione è sotto forma di una lista di stringhe, oppure viene lanciata l’eccezione Error in caso di errore. Se success è una funzione nella forma success(log, old_version, new_version, userdata), upgrade_database restituisce immediatamente un oggetto Deferred e la chiamata viene eseguita in modo asincrono; la callback success verrà invocata a tempo debito con il log dell’operazione, la vecchia versione dati, la nuova versione dati ed il parametro userdata.

Avvertimento

E” necessaria la password del server per poter eseguire questa operazione.

Esempi

Di seguito vengono riportati alcuni esempi di utilizzo della classe Client; si assume che ci sia un server Konga disponibile su localhost e che esista su di esso un database SQLite «demo» inizializzato con i dati di esempio.

Esempio di connessione e lista dell’archivio clienti presenti sul database:

import kongalib

c = kongalib.Client()
c.connect(host='localhost')
c.open_database('sqlite', 'demo')
c.authenticate('admin', '')
results = c.select_data('EB_ClientiFornitori', ['Codice', 'RagioneSociale'], 'Tipo = 1')
for row in results:
        print row

Esempio di come ottenere tutto il record di un documento fiscale (testata e righe):

import kongalib

def print_data(data, indent=1):
        # Stampa i dati, tralasciando le chiavi speciali (che cominciano con '@')
        lines = [ '%s: %s' % (key, value) for key, value in data.iteritems() if not key.startswith('@') ]
        print "\n".join((indent * "\t") + line for line in lines)

c = kongalib.Client()
c.connect(host='localhost')
c.open_database('sqlite', 'demo')
c.authenticate('admin', '')
record = c.get_record('EB_DocumentiFiscali', 11, code_azienda='00000001')
print "Testata:"
print_data(record)
rows = record.get('@rows', [])
for i, row in enumerate(rows):
        print "\tRiga %d:" % (i + 1)
        print_data(row, 2)