Wellcome alla seconda parte del mio tutorial su come salvare il database a Dropbox dall'interno di un'applicazione per cellulari Cordova. Qui vedremo come gestire il backup e il ripristino di un database utilizzando un utile plugin: SQLite Porter di Dave Alden. Il plugin è fantastico, funziona alla grande e lascia che condivida con te che sono davvero orgoglioso di essere entrato a far parte del gruppo dei contributori risolvendo un piccolo bug che impediva di utilizzare con successo exportDbToSql() e importDbFromSql().
Plugin SQLite Porter
SQLite Porter ti consente di esportare e importare un database utilizzando solo poche righe di codice. È possibile esportare il database in un file json o in un file sql utilizzando exportDbToJson() e exportDbToSql() funzioni. Per importare un database è possibile utilizzare le funzioni corrispondenti importJsonToDb() e importSqlToDb().
Così, apri il prompt dei comandi o la finestra del terminale e vai alla root del tuo progetto, tipo di allora:
cordova plugin add uk.co.workingedge.cordova.plugin.sqliteporter
È tutto: il plugin è pronto per noi.
Gestione dei file: cordova-plugin-file
Ma i file devono essere gestiti: dobbiamo crearli e le loro directory, dobbiamo essere in grado di leggere il loro contenuto e di scrivere contenuto su file. Per fare ciò, installeremo un importante plugin cordova che viene utilizzato per leggere e scrivere file all'interno del sistema operativo host. Dovresti ancora avere il tuo terminale (o prompt dei comandi) aprire nella directory principale del progetto (altrimenti, quindi aprilo e vai lì). Digita questo:
Cordova plugins aggiungere cordova-plugin-file
Esportazione del database in un file di backup
Tutto ok! Possiamo finalmente digitare del codice, adesso! Per prima cosa scriveremo la funzione che esporta effettivamente il nostro database e scrive un file di dump mysql: mettere il seguente codice prima della funzione principale di jQuery.
Se vuoi approfondire l'API del file system, Suggerisco di leggere, oltre all'obbligatorio Pagina man di Cordova, due ottimi articoli https://www.html5rocks.com/en/tutorials/file/filesystem/ e https://www.neontribe.co.uk/cordova-file-plugin-examples/. |
funzione exportBackup() { var successFn = funzione (SQL) { window.resolveLocalFileSystemURL(cordova.file.dataDirectory, funzione (dirEntry) { dirEntry.getDirectory("/ dropboxTestBackup", {creare: vero}, funzione (dirEntry) { dirEntry.getFile("dropboxTestBackup.sql", {creare: vero}, funzione (fileEntry) { mettere in guardia("Il file " + fileEntry.name + ' è stato creato nella seguente directory: Android/data/com.example.dropboxTest/files/dropboxTestBackup/'); writeFile(fileEntry, SQL); }); }, onErrorCreateFile); }, onErrorCreateDir); }; cordova.plugins.sqlitePorter.exportDbToSql(Db, { successoFn: successoFn }); } function onErrorCreateFile(e) { console.log('Errore durante la creazione del file: ' + e); } function onErrorCreateDir(e) { console.log('Errore durante la creazione della directory: ' + e); }
Analizziamo questo codice riga per riga. Come potete vedere, la funzione in cui è suddiviso 2 sezioni: il primo è la funzione di callback, il latetr è la funzione SQLite Porter che esporta effettivamente il database e quindi chiama la funzione di callback. Questa seconda parte è abbastanza semplice e non abbiamo nulla di interessante da notare al riguardo. Ma la funzione di calback ci permette di verificare come Cordova gestisce l'accesso e la manipolazione di file e directory.
Codice anatomia
Per prima cosa troviamo il file resolLocalFileSystemURL() (Vedere qui: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/index.html#where-to-store-files). A partire dalla versione 1.2, per ogni directory del file system importante viene fornito un URL:
Ogni URL è nel modulo file:///percorso / a / spot /, e può essere convertito in un file
DirectoryEntry
utilizzandowindow.resolveLocalFileSystemURL()
.
Passiamo a questa funzione il parametro cordova.file.dataDirectory: stiamo dicendo a Cordova che vogliamo archiviare il nostro file nella memoria interna. Questo è il metodo consigliato per memorizzare i dati persistenti dell'applicazione perché è accessibile esclusivamente dalla nostra applicazione. Lo verificheremo più avanti, quando avremo già creato il nostro file di backup. Così cordova.file.dataDirectory è uguale al percorso /sdcardAndroid / data / com.codingfix.dropboxTest / e viene convertito in un oggetto di tipo Voce di directory abbiamo chiamato dirEntry. dirEntry oggetto viene restituito dalla funzione anonima di callback che usiamo in resolLocalFileSystemURL(): window.resolveLocalFileSystemURL(cordova.file.dataDirectory, funzione (dirEntry) {
Esaminiamo la nostra funzione di callback: vediamo immediatamente che usiamo un metodo dell'oggetto Voce di directory, il metodo getDirectory() e lo passiamo 2 parametri e un'altra funzione di callback anonima: dirEntry.getDirectory('/dropboxTestBackup', {creare: vero}, funzione (dirEntry) {
Il metodo getDirectory() accettare quattro parametri (qui ne usiamo solo tre): una stringa che rappresenta il percorso relativo di una directory, un valore booleano che imposta se la directory deve essere creata se non trovata e due funzioni di callback per il successo e l'errore (questo non è usato nel nostro esempio). In altre parole, la nostra app sta dicendo ad Android di cercare la directory /sdcardAndroid / data / com.codingfix.dropboxTest / e per creare in quella directory una nuova directory chiamata dropboxTestBackup dove memorizzeremo i nostri file di backup.
La funzione di callback utilizza il nuovo oggetto di tipo Voce di directory creato dal metodo getDirectory() per creare il file di backup stesso: dirEntry.getFile('dropboxTestBackup.sql', {creare: vero}, funzione (fileEntry) { . Questa volta usiamo il metodo prendi il file() che è quasi identico al metodo getDirectory() usato sopra con l'ovvia differenza che crea un file invece di una directory e restituisce un riferimento a quel file. Usiamo l'oggetto fileEntry nell'ultima funzione di callback dove avvisiamo l'utente dell'applicazione che il file è stato creato con successo e scriviamo i nostri dati nel file:
mettere in guardia("Il file: " + fileEntry.name + ' è stato creato nella seguente directory: Android/data/com.example.dropboxTest/files/dropboxTestBackup/'); writeFile(fileEntry, SQL);
Ehi, Cos'è quello?!? Non abbiamo mai parlato di un file writeFile() funzione!!! – Ti sento dire. Non preoccuparti, ragazzi: Ne parleremo proprio ora 🙂
Scrittura di file
sì, dobbiamo scrivere i dati su un file, lo sapevamo, non è vero? Quindi guarda questa funzione (e tieniti pronto per sapere come leggere i file, più avanti in questo articolo):
funzione writeFile(fileEntry, di datiObj) { // Creare un oggetto FileWriter per il nostro FileEntry. fileEntry.createWriter(funzione (Scrittore di file) { fileWriter.onwriteend = funzione () { console.log("Scrittura del file riuscita..."); readFile(fileEntry); }; fileWriter.write(di datiObj); }, onErrorWriteFile); } function onErrorWriteFile(e) { console.log('Errore durante la scrittura del file: ' + e.toString()); } funzione readFile(fileEntry) { fileEntry.file(funzione (file) { var reader = nuovo FileReader(); reader.onloadend = funzione () { console.log("Lettura del file riuscita: " + fileEntry.fullPath + " - soddisfare: " + questo.risultato); return this.result; }; lettore.leggereAsTesto(file); }, onErrorReadFile); } funzione onErrorReadFile(e) { console.log('Errore durante la lettura del file: ' + e); }
La funzione è abbastanza semplice: accetta e basta 2 params, l'oggetto file che punta al file fisico creato nel nostro file system e i dati da scrivere nel file: writeFile(fileEntry, SQL); Questa funzione utilizza quindi internamente il file readFile() per leggere il file appena creato e visualizzarne il contenuto nella console. Come abbiamo notato sopra, memorizzare il file nella memoria interna (poiché è consigliato per motivi di sicurezza) non ci permette di trovare questo file utilizzando applicazioni di terze parti. Né il tuo file manager preinstallato né uno di terze parti può vedere questo file (dropboxTestBackup.sql) né la directory in cui viene creato il file (/dropboxTestBackup), quindi questo è l'unico modo in cui dobbiamo verificare se tutto è andato bene.
Se vuoi creare un file pubblico, accessibile dal tuo file manager Android o anche dal tuo computer quando il tuo dispositivo Android è collegato tramite un cavo USB, devi usare Directory dei dati esterni invece di dataDirectory, ma questo espone ai tuoi file l'accesso a software di terze parti. Quindi sentiti libero di usare Directory dei dati esterni durante lo sviluppo, per semplificare il debug della tua app, ma tieni presente di sostituirlo con dataDirectory quando in produzione. |
Va bene. Finora abbiamo imparato come esportare il nostro database in un formato sql e come scrivere questi dati in un file all'interno del nostro file system. Ora dobbiamo importare questi dati nel nostro database (se qualcosa inavvertitamente avesse cancellato i nostri dati).
Importare un file di backup nel nostro database
Quindi ora vogliamo eseguire l'operazione opposta, leggere i dati da un file e utilizzarli per ripristinare il nostro database dell'applicazione. Il codice è facilmente comprensibile considerando ciò che abbiamo imparato prima.
funzione importBackup(daDropbox) { var percorsoToFile = cordova.file.dataDirectory + '/dropboxTestBackup/dropboxTestBackup.sql'; window.resolveLocalFileSystemURL(percorsoAFile, funzione (fileEntry) { fileEntry.file(funzione (file) { var reader = nuovo FileReader(); reader.onloadend = funzione (e) { var successFn = funzione () { mettere in guardia('Database ripristinato con successo!'); caricaPaesi(); caricaUtenti(); }; cordova.plugins.sqlitePorter.importSqlToDb(Db, questo.risultato, { successoFn: successoFn }); }; lettore.leggereAsTesto(file); }, onErrorLoadFile); }, onErrorLoadFs); } funzione suErrorLoadFile(e){ console.log('Errore durante la lettura del file: ' + e.toString()); } funzione onErrorLoadFs(e) { console.log('Errore durante il caricamento del file system: ' + e); }
Impostiamo prima il percorso del nostro file di backup, quindi usiamo resolLocalFileSystemURL() prendere il fileEntry per leggere il contenuto del file e usarlo nella funzione di callback onloadend() come parametro a cui dare cordova.plugins.sqlitePorter.importSqlToDb(). Una volta caricato il file, avvisiamo l'utente e chiamiamo le nostre due funzioni per completare i nostri controlli. Ecco, i giochi sono fatti!
Fai funzionare i pulsanti!
Ti ricordi il codice che avevamo scritto nel nostro indice.js file per allegare il gestore di eventi ai nostri pulsanti? Sembrava in questo modo:
$('#creaDB').clic(funzione (e) { e.preventDefault(); creare tabelle(); }); $('#exportDB').clic(funzione (e) { e.preventDefault(); }); $('#DB vuoto').clic(funzione (e) { e.preventDefault(); dropTables(); }); $('#importDB').clic(funzione (e) { e.preventDefault(); });
Ora dobbiamo aggiungere una chiamata a exportBackup() e importBackup() funzioni per rendere questo blocco di codice leggermente diverso:
$('#creaDB').clic(funzione (e) { e.preventDefault(); creare tabelle(); }); $('#exportDB').clic(funzione (e) { e.preventDefault(); exportBackup(falso); }); $('#DB vuoto').clic(funzione (e) { e.preventDefault(); dropTables(); }); $('#importDB').clic(funzione (e) { e.preventDefault(); importBackup(falso); });
Ti mostro come il tutto indice.js il file dovrebbe apparire così lontano:
era app = { inizializzare: funzione () { document.addEventListener('Deviceready', this.onDeviceReady.bind(Questo), falso); }, onDeviceReady: funzione () { this.receivedEvent('Deviceready'); }, receivedEvent: funzione (Id) { var parentElement = document.getElementById(Id); var listeningElement = parentElement.querySelector('.ascoltando'); var receivedElement = parentElement.querySelector('.Received'); listeningElement.setAttribute('stile', 'Schermo:nessuna;'); ricevutoElement.setAttribute('stile', 'Schermo:bloccare;'); console.log('Evento ha ricevuto: ' + Id); } }; app.initialize(); var db = window.openDatabase("dropbox_test", "1.0", "Test di importazione/esportazione del processo di dati con Dropbox", 200000); funzione createCountryTable() { db.transaction(funzione (Tx) { tx.executeSql("DROP TABLE SE ESISTONO paesi"); tx.executeSql("CREA TABELLA SE NON ESISTE paesi (id INCREMENTO AUTOMATICO CHIAVE PRIMARIA INTEGER, paese INTEGER, codice TESTO)", [], countryCreatedSuccess, countryCreatedError); tx.executeSql("INSERIRE NEI paesi (Id, nazione, codice) VALORI (1, "Afghanistan", 'DI'),(2, «Albania», «AL»),(3, «Algeria», «DZ»),(4, 'Andorra', 'ANNO DOMINI'),(5, «Angola», 'A'),(6, 'Antigua e Barbuda', «AG»),(7, "Argentina", 'INSIEME A'),(8, «Armenia», 'SONO'),(9, 'Australia', 'A'),(10, «Austria», 'A'), (11, 'Azerbaigian', 'IL'),(12, «Bahamas, Il', «BS»),(13, 'Bahrein', «BH»),(14, "Bangladesh", «BD»),(15, 'Barbado', «BB»),(16, 'Bielorussia', 'DI'),(17, 'Belgio', 'ESSERE'),(18, 'Belize', «BZ»), (19, 'benin', 'BJ'),(20, 'Bhutan', «BT»),(21, 'Bolivia', «BO»),(22, 'Bosnia Erzegovina', «BA»),(23, "Botswana", 'bianco e nero'),(24, 'Brasile', 'BR'),(25, 'Brune', «BN»),(26, «Bulgaria», «BG»),(27, 'Burkina Faso', «BF»),(28, 'Burundi', 'CON UN'),(29, 'Cambogia', 'KH'),(30, 'Camerun', «CM»),(31, «Canada», 'QUELLO'),(32, «Capo Verde», «CV»),(33, "Repubblica Centrafricana", «CF»),(34, 'Ciad', 'TD'),(35, «Cile», «CL»),(36, 'Cina, Repubblica popolare di', «NC»),(37, «Colombia», «CO»),(38, "Comore", «KM»),(39, "Congo", (Congo ? Kinshasa)', 'CD'),(40, "Congo", (Congo ? Brazzaville)', 'CG'),(41, 'Costa Rica', «CR»), (42, 'Costa d'Avorio (Costa d'Avorio)', «CI»), (43, 'Croazia', "Risorse umane"), (44, «Cuba», 'INSIEME A'), (45, 'Cipro', «CY»), (46, 'Repubblica Ceca', "CZ"),(47, 'Danimarca', 'non so'), (48, 'Gibuti', "DJ"), (49, "Dominica", «DM»), (50, 'Repubblica Dominicana', 'FARE'), (51, «Ecuador», "CE"), (52, 'Egitto', 'PER ESEMPIO'), (53, 'Il salvatore', «SV»), (54, 'Guinea Equatoriale', 'GQ'), (55, 'Eritrea', 'È'), (56, «Estonia», 'SÌ'), (57, 'Etiopia', 'E'), (58, «Figi», «FJ»), (59, 'Finlandia', 'ESSERE'), (60, 'Francia', «FR»), (61, «Gabon», «GA»),(62, «Gambia, Il', «GM»),(63, «Georgia», 'DARE'),(64, 'Germania', 'A PARTIRE DAL'), (65, «Ghana», «GH»), (66, 'Grecia', «GR»), (67, "Grenata", «GD»), (68, 'Guatemala', «GT»), (69, «Guinea», «GN»), (70, "Guinea-Bissau", 'GW'), (71, 'Guyana', 'GY'), (72, 'Haiti', «HT»), (73, 'Honduras', «HN»), (74, 'Ungheria', «HU»), (75, 'Islanda', 'È'), (76, «India», 'IN'), (77, «Indonesia», «Documento d'identità»), (78, "Iran", «IR»), (79, 'Iraq', 'QI'), (80, 'Irlanda', 'CIOÈ'), (81, 'Israele', «IL»), (82, 'Italia', 'ESSO'),(83, 'Giamaica', «JM»), (84, 'Giappone', «JP»), (85, 'Giordania', 'GIÀ'), (86, "Kazakistan", 'KZ'), (87, 'Kenia', 'Ke'), (88, "Kiribati", 'Ki'), (89, 'Corea, Nord', «KP»), (90, 'Corea, Sud', «KR»), (91, «Kuwait», 'KW'),(92, "Kirghizistan", «KG»), (93, 'Laos', 'IL'), (94, 'Lettonia', «LV»), (95, 'Libano', 'LIBBRE'), (96, 'Lesotho', «LS»), (97, «Liberia», «LR»), (98, 'Libia', 'LY'), (99, "Liechtenstein", 'AL'), (100, 'Lituania', «LT»), (101, "Lussemburgo", «LU»), (102, "Macedonia", «MK»), (103, 'Madagascar', "MG"), (104, 'Malawi', «MW»), (105, 'Malesia', 'MIO'), (106, 'Maldive', 'MV'), (107, «Mali», «ML»), (108, «Malta», 'MT'), (109, 'Isole Marshall', «MH»), (110, "Mauritania", 'SIG'), (111, "Maurizio", «MU»), (112, 'Messico', 'MX'), (113, "Micronesia", 'FM'), (114, "Moldavia", «Dottore»), (115, "Monaco", 'MC'), (116, 'Mongolia', «MN»), (117, «Montenegro», 'IO'), (118, 'Marocco', «MA»), (119, "Mozambico", «MZ»), (120, «Myanmar (Birmania)', «MM»), (121, «Namibia», 'N / A'), (122, 'Nauru', 'NO'), (123, 'Nepal', 'PER ESEMPIO'), (124, 'Olanda', «NL»), (125, 'Nuova Zelanda', «Nuova Zelanda»), (126, 'Nicaragua', «NI»), (127, «Niger», 'NATO'), (128, «Nigeria», «NG»), (129, 'Norvegia', «NO»), (130, 'Oman', 'SE'), (131, «Pakistan», «PK»), (132, 'Pala', «PW»), (133, «Panama», 'PAPÀ'), (134, 'Papua Nuova Guinea', «PG»), (135, "Paraguay", 'PI'), (136, 'Perù', 'SU'), (137, "Filippine", 'PH'), (138, 'Polonia', «PL»), (139, 'Portogallo', «PT»), (140, «Qatar», «QA»), (141, «Romania», «RO»), (142, «Russia», «RU»), (143, 'Ruanda', «RW»), (144, "Saint Kitts e Nevis", 'KN'), (145, 'Santa Lucia', «LC»), (146, "Saint Vincent e Grenadine", 'TU'), (147, 'Samoa', «WS»), (148, 'San Marino', «SM»), (149, "Sao Tomé e Principe", 'NS'), (150, 'Arabia Saudita', 'A'), (151, «Senegal», «SN»), (152, «Serbia», 'RS'), (153, "Seychelles", 'NS'), (154, 'Sierra Leone', «SL»), (155, «Singapore», «SG»), (156, "Slovacchia", 'SK'), (157, "Slovenia", 'E'), (158, 'Isole Salomone', «SB»), (159, «Somalia», 'COSÌ'), (160, 'Sud Africa', 'PER'), (161, 'Spagna', 'È'), (162, 'Sri Lanka', 'PAGINA'), (163, 'Sudan', 'SD'), (164, «Suriname», «SR»), (165, "Swaziland", 'SZ'), (166, 'Svezia', 'LO SO'), (167, 'Svizzera', «CH»), (168, 'Siria', 'IL SUO'), (169, "Tagikistan", 'TJ'), (170, «Tanzania», 'ZZ'), (171, 'Tailandia', 'NS'), (172, Timor Est (Timor Est)', 'TL'), (173, 'Andare', «TG»), (174, 'Tonga', 'A'), (175, 'Trinidad e Tobago', «TT»), (176, «Tunisia», «TN»), (177, 'Tacchino', «TR»), (178, "Turkmenistan", 'TM'), (179, 'Tuvalu', 'TV'), (180, 'Uganda', 'UG'), (181, 'Ucraina', «UA»), (182, 'Emirati Arabi Uniti', «AE»), (183, 'Regno Unito', «GB»), (184, 'Stati Uniti', 'NOI'), (185, «Uruguay», 'U'), (186, «Uzbekistan», 'A'), (187, Vanuatu, 'VISTO'), (188, 'Città del Vaticano', «VA»), (189, 'Venezuela', 'E'), (190, 'Vietnam', «VN»), (191, 'Yemen', 'VOI'), (192, «Zambia», «ZM»), (193, «Zimbabwe», 'Z W'), (194, 'Abcasia', 'DARE'), (195, 'Cina, Repubblica di (Taiwan)', 'TW'), (196, "Nagorno-Karabakh", 'IL'), (197, "Cipro settentrionale", «CY»), (198, "Pridnestrovie" (Transnistria)', «Dottore»), (199, 'Somalia', 'COSÌ'), (200, "Ossezia del Sud", 'DARE'), (201, "Isole Ashmore e Cartier", 'A'), (202, 'Isola di Natale', 'CX'), (203, «Cocco (Keeling) Isole', «CC»), (204, "Isole del Mar dei Coralli", 'A'), (205, "Isole Heard e McDonald", «HM»), (206, "Isola Norfolk", «NF»), (207, 'Nuova Caledonia', «NC»), (208, 'Polinesia francese', «PF»), (209, 'Mayotte', 'YT'), (210, "San Bartolomeo", 'GP'), (211, 'San Martino', 'GP'), (212, "San Pietro e Miquelon", "Primo giorno"), (213, "Wallis e Futuna", «WF»), (214, "Terre australi e antartiche francesi", «TF»), (215, "Isola di Clipperton", «PF»), (216, "Isola Bouvet", 'VB'), (217, 'Isole Cook', «CK»), (218, 'Nuovo', 'NON'), (219, 'Tokelau', «TK»), (220, 'Guernsey', 'GG'), (221, 'Isola di Man', 'IO SONO'), (222, 'Maglia', 'JE'), (223, 'Anguilla', 'IA'), (224, 'Bermuda', «BM»), (225, 'Territorio britannico dell'Oceano Indiano', 'IO'), (226, "Aree di base sovrana britannica", ''), (227, 'Isole Vergini Britanniche', «VG»), (228, 'Isole Cayman', 'KY'), (229, 'Isole Falkland (Isole Falkland)', «FK»), (230, 'Gibilterra', 'DARE'), (231, "Monserrato", 'SM'), (232, "Isole Pitcairn", «PN»), (233, 'Sant'Elena', 'SH'), (234, "Georgia del Sud" & Isole Sandwich Meridionali", «GS»), (235, 'Isole Turks e Caicos', «TC»), (236, 'Isole Marianne settentrionali', 'deputato'), (237, "Porto Rico", «PR»), (238, 'Samoa americane', 'COME'), (239, "Isola del panettiere", 'UN'), (240, 'Guam', «GU»), (241, 'Isola Howland', 'UN'), (242, "Isola Jarvis", 'UN'), (243, "Atollo Johnston", 'UN'), (244, 'Barriera corallina di Kingman', 'UN'), (245, "Isole intermedie", 'UN'), (246, 'Isola Navassa', 'UN'), (247, "Atollo di Palmira", 'UN'), (248, 'NOI. Isole Vergini', 'NOI'), (249, "Isola del risveglio", 'UN'), (250, 'Hong Kong', «HK»), (251, 'Macao', «MO»), (252, 'Isole Faroe', 'NS'), (253, 'Groenlandia', «GL»), (254, 'Guiana francese', «GF»), (255, 'Guadalupa', 'GP'), (256, "Martinica", 'MQ'), (257, 'Riunione', 'RIF'), (258, 'Una terra', 'ASCIA'), (259, 'Aruba', 'AW'), (260, 'Antille Olandesi', 'UN'), (261, 'Svalbard', «SJ»), (262, 'Ascensione', «AC»), (263, "Tristano da Cunha", «TA»), (268, "Territorio antartico australiano", 'QA'), (269, "Dipendenza Ross", 'QA'), (270, "Isola Pietro I", 'QA'), (271, "Terra della Regina Maud", 'QA'), (272, "Territorio antartico britannico", 'QA');", [], countryFilledSuccess, countryFilledError); funzione countryCreatedSuccess() { console.log('Tabella dei paesi creata con successo!'); } funzione countryCreatedError(Tx, errore) { console.log(messaggio di errore); } funzione countryFilledSuccess() { console.log('Tabella dei paesi compilata con successo!'); caricaPaesi(); } funzione countryFilledError(Tx, errore) { console.log(messaggio di errore); } }); } funzione createUsersTable() { db.transaction(funzione (Tx) { tx.executeSql("ELIMINA TABELLA SE ESISTE utenti"); tx.executeSql("CREA TABELLA SE NON ESISTE utenti (id INCREMENTO AUTOMATICO CHIAVE PRIMARIA INTEGER, nome TEXT, cognome TEXT, indirizzo_email TESTO, paese TESTO)", [], userCreatedSuccess, UserCreatedError); tx.executeSql("INSERIRE NEGLI utenti (Id, nome di battesimo, cognome, indirizzo email, nazione) VALORI (1, 'Giovanni', 'Dina', 'john.doe@email.com', 'STATI UNITI D'AMERICA'), (2, 'Miguel', 'Olivare', 'miguel.olivares.Doe@email.es', 'Spagna'), (3, 'Franco', 'Kuttermeyer', 'frankut@email.de', 'Germania'), (4, 'Marianna', 'Jolie', 'mariannejolie@email.fr', 'Francia')", [], userFilledSuccess, UserFilledError); funzione userCreatedSuccess() { console.log('Tabella degli utenti creata con successo!'); } funzione userCreatedError(Tx, errore) { console.log(messaggio di errore); } funzione userFilledSuccess() { console.log('Tabella degli utenti compilata con successo!'); caricaUtenti(); } funzione userFilledError(Tx, errore) { console.log(messaggio di errore); } }); } funzione createTables() { createCountryTable(); createUsersTable(); } funzione dropCountriesTable() { db.transaction(funzione (Tx) { tx.executeSql("DROP TABLE SE ESISTONO paesi", [], dropPaesiSuccesso, dropCountriesError); funzione dropPaesiSuccesso() { console.log('Tabella dei paesi eliminata con successo!'); caricaPaesi(); } funzione dropCountriesError(Tx, errore) { console.log(messaggio di errore); } }); } funzione dropUsersTable() { db.transaction(funzione (Tx) { tx.executeSql("ELIMINA TABELLA SE ESISTE utenti", [], dropUsersSuccess, dropUsersError); funzione dropUsersSuccess() { console.log('Tabella degli utenti eliminata con successo!'); caricaUtenti(); } funzione dropUsersError(Tx, errore) { console.log(messaggio di errore); } }); } funzione dropTables() { dropUsersTable(); dropCountriesTable(); } funzione caricoPaesi() { var qry = "SELEZIONA ID, paese DA paesi"; db.transaction(funzione (Tx) { tx.executeSql(qry, [], querySuccess, queryError); funzione querySuccess(Tx, dati) { $('seleziona#paesi').figli().rimuovere(); var paesi = {}; per (var io = 0; io < dati.righe.lunghezza; io++) { $('seleziona#paesi').aggiungere('<valore opzione="' + dati.righe[io].Id + '">' + dati.righe[io].nazione + '</opzione>'); } } funzione queryError(transazione, errore) { console.log('Query errorHandler' + messaggio di errore + 'in interrogazione' + qry); //usiamo la funzione di callback di errore per svuotare i controlli della pagina $('seleziona#paesi').figli().rimuovere(); $('seleziona#paesi').aggiungere('<opzione>Non sono stati trovati dati sul paese!</opzione>'); } }); } funzione loadUsers() { var qry = "SELECT nome, cognome, indirizzo email, paese FROM utenti"; db.transaction(funzione (Tx) { tx.executeSql(qry, [], querySuccess, queryError); funzione querySuccess(Tx, dati) { $('#utenti').figli().rimuovere(); per (var io = 0; io < dati.righe.lunghezza; io++) { $('#utenti').aggiungere('<Li = classe"cadere in picchiata">' + dati.righe[io].nome di battesimo + ' ' + dati.righe[io].cognome + '<ul class ="sottomenu"><in>' + dati.righe[io].indirizzo email + '</in><in>' + dati.righe[io].nazione + '</in></il></in>'); } } funzione queryError(transazione, errore) { console.log('Query errorHandler' + messaggio di errore + 'in interrogazione' + qry); //usiamo la funzione di callback di errore per svuotare i controlli della pagina $('#utenti').figli().rimuovere(); $('#utenti').aggiungere('<opzione>Nessun dato utente trovato!</opzione>'); } }); } funzione exportBackup() { var successFn = funzione (SQL) { window.resolveLocalFileSystemURL(cordova.file.dataDirectory, funzione (dirEntry) { dirEntry.getDirectory("/ dropboxTestBackup", {creare: vero}, funzione (dirEntry) { dirEntry.getFile("dropboxTestBackup.sql", {creare: vero}, funzione (fileEntry) { mettere in guardia("Il file " + fileEntry.name + ' è stato creato nella seguente directory: Android/data/com.example.dropboxTest/files/dropboxTestBackup/'); writeFile(fileEntry, SQL); }); }, onErrorCreateFile); }, onErrorCreateDir); }; cordova.plugins.sqlitePorter.exportDbToSql(Db, { successoFn: successoFn }); } function onErrorCreateFile(e) { console.log('Errore durante la creazione del file: ' + e); } function onErrorCreateDir(e) { console.log('Errore durante la creazione della directory: ' + e); } funzione writeFile(fileEntry, di datiObj) { // Creare un oggetto FileWriter per il nostro FileEntry. fileEntry.createWriter(funzione (Scrittore di file) { fileWriter.onwriteend = funzione () { console.log("Scrittura del file riuscita..."); readFile(fileEntry); }; fileWriter.write(di datiObj); }, onErrorWriteFile); } function onErrorWriteFile(e) { console.log('Errore durante la scrittura del file: ' + e.toString()); } funzione readFile(fileEntry) { fileEntry.file(funzione (file) { var reader = nuovo FileReader(); reader.onloadend = funzione () { console.log("Lettura del file riuscita: " + fileEntry.fullPath + " - soddisfare: " + questo.risultato); return this.result; }; lettore.leggereAsTesto(file); }, onErrorReadFile); } funzione onErrorReadFile(e) { console.log('Errore durante la lettura del file: ' + e); } funzione importBackup(daDropbox) { var percorsoToFile = cordova.file.dataDirectory + '/dropboxTestBackup/dropboxTestBackup.sql'; window.resolveLocalFileSystemURL(percorsoAFile, funzione (fileEntry) { fileEntry.file(funzione (file) { var reader = nuovo FileReader(); reader.onloadend = funzione (e) { var successFn = funzione () { mettere in guardia('Database ripristinato con successo!'); caricaPaesi(); caricaUtenti(); }; cordova.plugins.sqlitePorter.importSqlToDb(Db, questo.risultato, { successoFn: successoFn }); }; lettore.leggereAsTesto(file); }, onErrorLoadFile); }, onErrorLoadFs); } funzione suErrorLoadFile(e){ console.log('Errore durante la lettura del file: ' + e.toString()); } funzione onErrorLoadFs(e) { console.log('Errore durante il caricamento del file system: ' + e); } $(documento).pronto(funzione () { caricaPaesi(); caricaUtenti(); $('#creaDB').clic(funzione (e) { e.preventDefault(); creare tabelle(); }); $('#exportDB').clic(funzione (e) { e.preventDefault(); exportBackup(falso); }); $('#DB vuoto').clic(funzione (e) { e.preventDefault(); dropTables(); }); $('#importDB').clic(funzione (e) { e.preventDefault(); importBackup(falso); }); $('#utenti').su('clic', 'li.dropdown', funzione (e) { e.preventDefault(); console.log($(Questo).testo()); var elementi = $(Questo).fratelli().trova('ul.sottomenu'); articoli.ciascuno(funzione () { Se ($(Questo).è(':visibile')) { $(Questo).scorrere verso l'alto('Lento'); } }); $(Questo).trova('ul.sottomenu').slideToggle(); }); });
Ora possiamo esportare il nostro database in un file locale e se necessario, ripristinalo dal file di backup. Basta eseguire l'app, e segui questi passaggi per testare l'app:
- Rubinetto Crea database per creare il database (se non l'hai ancora fatto)
- Esportalo toccando Esporta database pulsante
- Ora tocca Database vuoto pulsante per eliminare tutti i tuoi dati
- e poi tocca Importa database per rivedere i tuoi dati dal vivo!
grande, non è vero?
Ma vogliamo essere sicuri che il nostro utente possa recuperare i suoi dati anche se ha disinstallato la nostra applicazione in un momento di disturbo mentale e poi, una volta che è tornato alla ragione, l'ha reinstallato. Quindi dobbiamo offrirgli la possibilità di salvare il suo file di backup su un host esterno. Indovina? si, Casella Personale! E questo sarà l'argomento del prossimo, capitolo finale di questo tutorial.