Guardar la base de datos de Cordova en Dropbox

Cómo guardar su base de datos para Dropbox (y cómo restaurarla) desde una aplicación de Cordova – Sólo Android (parte 2)

Bienvenidos a la segunda parte de mi tutorial sobre cómo salvar su base de datos a Dropbox desde dentro de una aplicación móvil Cordova. Here we’ll see how to manage backup and restore of a database using a helpful plugin: Portero de SQLite por Dave Alden. El complemento es fantástico, it works great and let me share with you I’m proud indeed to have joined the contributors group fixing a small bug which prevented to successfully use exportDbToSql() y importDbFromSql().

Complemento SQLite Porter

SQLite Porter le permite exportar e importar una base de datos usando solo unas pocas líneas de código. Puede exportar la base de datos a un archivo json o un archivo sql usando exportDbToJson() y exportDbToSql() funciones. Para importar una base de datos, puede utilizar las funciones correspondientes. importJsonToDb() y importSqlToDb().

Entonces, abra el símbolo del sistema o la ventana de su terminal y navegue hasta la raíz de su proyecto, luego escribe:

complemento de cordova agregar uk.co.workingedge.cordova.plugin.sqliteporter

Eso es todo: el complemento está listo para nosotros.

Administrar archivos: archivo-plugin-cordova

Pero los archivos deben administrarse: tenemos que crearlos a ellos y sus directorios, debemos poder leer su contenido y escribir contenido en archivos. To do so we’re going to install an important cordova plugin which is used to read and write files within the host OS. Todavía deberías tener tu terminal (o símbolo del sistema) abrir en el directorio raíz de su proyecto (si no, luego ábrelo y ve allí). Escribe esto:

Los complementos de cordova agregan el archivo cordova-plugin-file

Exportar la base de datos a un archivo de respaldo

Está bien! Finalmente podemos escribir un código, ahora! First we’ll write the function which actually exports our database and writes down a mysql dump file: poner el siguiente código antes de la función principal de jQuery.

Si desea profundizar en la API del sistema de archivos, Sugiero leer, además de lo obligatorio Página de manual de Cordova, dos grandes artículos https://www.html5rocks.com/en/tutorials/file/filesystem/ y https://www.neontribe.co.uk/cordova-file-plugin-examples/.
función exportBackup() {
	var successFn = función (.sql) {
		window.resolveLocalFileSystemURL(cordova.file.dataDirectory, función (dirEntry) {
			dirEntry.getDirectory('/ dropboxTestBackup', {crear: cierto}, función (dirEntry) {
				dirEntry.getFile('dropboxTestBackup.sql', {crear: cierto}, función (fileEntry) {
					alerta("El archivo " + fileEntry.name + 'se ha creado en el siguiente directorio: Android / data / com.example.dropboxTest / files / dropboxTestBackup / ');
					writeFile(fileEntry, .sql);
				});
			}, onErrorCreateFile);
		}, onErrorCreateDir);
	};
	cordova.plugins.sqlitePorter.exportDbToSql(.db, {
		successFn: successFn
	});
}

función onErrorCreateFile(mi) {
	consola.log('Error al crear el archivo: ' + mi);
}

función onErrorCreateDir(mi) {
	consola.log('Error al crear el directorio: ' + mi);
}

Let’s analyze this code line by line. Como puedes ver, la función en la que se divide 2 secciones: la primera es la función de devolución de llamada, latetr es la función SQLite Porter que realmente exporta la base de datos y luego llama a la función de devolución de llamada. Esta segunda parte es bastante simple y no tenemos nada interesante que señalar al respecto.. Pero la función calback nos permite comprobar cómo Cordova gestiona el acceso y la manipulación de archivos y directorios.

Anatomía del código

Primero encontramos el resolveLocalFileSystemURL() (mira aquí: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/index.html#where-to-store-files). A partir de la versión 1.2, para cada directorio importante del sistema de archivos se proporciona una URL:

Cada URL tiene el formato archivo:///camino / a / lugar /, y se puede convertir en un DirectoryEntry utilizando window.resolveLocalFileSystemURL().

Pasamos a esta función el parámetro cordova.file.dataDirectory: we’re telling Cordova we want to store our file in the Internal Storage. Este es el recomendado para almacenar cualquier dato persistente de la aplicación porque es accesible exclusivamente por nuestra aplicación.. We’ll check this later, when we’ll have already created our backup file. Entonces cordova.file.dataDirectory es igual al camino /sdcardAndroid / data / com.codingfix.dropboxTest / y se convierte en un objeto de tipo DirectoryEntry hemos llamado dirEntry. dirEntry El objeto es devuelto por la función anónima de devolución de llamada que usamos en resolveLocalFileSystemURL(): window.resolveLocalFileSystemURL(cordova.file.dataDirectory, función (dirEntry) {

Let’s examine our callback function: inmediatamente vemos que usamos un método del objeto DirectoryEntry, el método getDirectory() y lo pasamos 2 parámetros y otra función de devolución de llamada anónima: dirEntry.getDirectory(‘/dropboxTestBackup’, {crear: cierto}, función (dirEntry) {

El método getDirectory() aceptar cuatro parámetros (aquí solo usamos tres): una cadena que representa la ruta relativa de un directorio, un valor booleano que establece si el directorio debe crearse si no se encuentra y dos funciones de devolución de llamada para el éxito y el error (este no se usa en nuestro ejemplo). En otras palabras, nuestra aplicación le dice a Android que busque un directorio /sdcardAndroid / data / com.codingfix.dropboxTest / y crear en ese directorio un nuevo directorio llamado dropboxTestBackup where we’ll store our backup files.

La función de devolución de llamada usa el nuevo objeto de tipo DirectoryEntry creado por el método getDirectory() para crear el archivo de respaldo en sí: dirEntry.getFile(‘dropboxTestBackup.sql’, {crear: cierto}, función (fileEntry) { . Esta vez usamos el método Obtener el archivo() que es casi idéntico al método getDirectory() usado anteriormente con la diferencia obvia de que crea un archivo en lugar de un directorio y devuelve una referencia a ese archivo. Usamos el objeto fileEntry en la última función de devolución de llamada donde alertamos al usuario de la aplicación de que el archivo se ha creado correctamente y escribimos nuestros datos en el archivo:

alerta("El archivo: " + fileEntry.name + 'se ha creado en el siguiente directorio: Android / data / com.example.dropboxTest / files / dropboxTestBackup / '); 
writeFile(fileEntry, .sql);

Oye, qué es eso?!? Nunca hablamos de un writeFile() función!!! – Te oigo decir. Don’t worry, Chicos: we’re going to look at that right now 🙂

Escritura de archivos

si, tenemos que escribir datos en un archivo, Lo sabíamos, No es? Fíjate en esta función (y mantenerte listo para saber sobre la lectura de archivos, más adelante en este artículo):

función writeFile(fileEntry, dataObj) {
	// Crear un objeto FileWriter para nuestro FileEntry.
	fileEntry.createWriter(función (fileWriter (Escritor de archivos)) {
		fileWriter.onwriteend = función () {
			consola.log("Escritura exitosa de archivos...");
			readFile(fileEntry);
		};
		fileWriter.write(dataObj);
	}, onErrorWriteFile);
}

función onErrorWriteFile(mi) {
	consola.log('Error al escribir el archivo: ' + e.toString());
}

función readFile(fileEntry) {
	fileEntry.file(función (archivo) {
		var reader = nuevo FileReader();
		reader.onloadend = función () {
			consola.log("Lectura correcta del archivo: " + fileEntry.fullPath + " - contenido: " + this.result);
			return this.result;
		};
		reader.readAsText(archivo);
	}, onErrorReadFile);
}

función onErrorReadFile(mi) {
	consola.log('Error al leer el archivo: ' + mi);
}

La función es bastante simple: simplemente acepta 2 Parámetros, el objeto file que apunta al archivo físico creado en nuestro sistema de archivos y los datos que se van a escribir en el archivo: writeFile(fileEntry, .sql); A continuación, esta función utiliza internamente el método readFile() para leer el archivo recién creado y poner su contenido en la consola. Como hemos notado anteriormente, almacenar el archivo en el almacenamiento interno (ya que se recomienda por razones de seguridad) doesn’t allow us to find this file using any third party application. Ni su administrador de archivos preinstalado ni uno de terceros pueden ver este archivo (dropboxTestBackup.sql) ni el directorio donde se crea el archivo en (/dropboxTestBackup), así que esta es la única forma que tenemos de comprobar si todo salió bien.

 

Si desea crear un archivo público, accesible por su administrador de archivos de Android o incluso por su computadora cuando su dispositivo Android está conectado con un cable USB, tienes que usar externalDataDirectory en lugar de directorio de datos, pero esto expone sus archivos al acceso de software de terceros. Así que siéntete libre de usar externalDataDirectory mientras está en desarrollo, para facilitar la depuración de su aplicación, pero ten en cuenta que debes reemplazarlo con directorio de datos cuando en producción.

Bueno. Hasta ahora hemos aprendido cómo exportar nuestra base de datos en formato sql y cómo escribir estos datos en un archivo dentro de nuestro sistema de archivos.. Ahora tenemos que importar estos datos a nuestra base de datos. (si algo inadvertidamente borró nuestros datos).

Importar un archivo de respaldo a nuestra base de datos

Entonces ahora queremos realizar la operación opuesta, leer datos de un archivo y usarlos para restaurar la base de datos de nuestra aplicación. El código es fácilmente comprensible considerando lo que hemos aprendido antes..

función importBackup(desdeDropbox) {
	var rutaToArchivo = cordova.archivo.datosDirectorio + '/dropboxTestBackup/dropboxTestBackup.sql';
	window.resolveLocalFileSystemURL(pathToFile, función (fileEntry) {
		fileEntry.file(función (archivo) {
			var reader = nuevo FileReader();

			reader.onloadend = función (mi) {
				var successFn = función () {
					alerta('Base de datos restaurada con éxito!');
					loadPaíses();
					loadUsers();
				};
				cordova.plugins.sqlitePorter.importSqlToDb(.db, this.result, {
					successFn: successFn
				});
			};
			reader.readAsText(archivo);
		}, onErrorLoadFile);
	}, onErrorLoadFs);
}

función onErrorLoadFile(mi){
	consola.log('Error al leer el archivo: ' + e.toString());
}

función onErrorLoadFs(mi) {
	consola.log('Error al cargar el sistema de archivos: ' + mi);
}

Primero establecemos la ruta a nuestro archivo de respaldo, entonces usamos resolveLocalFileSystemURL() para obtener el fileEntry to read file’s content and to use them in callback function onloadend() como parámetro para dar a cordova.plugins.sqlitePorter.importSqlToDb(). Una vez que se carga el archivo, alertamos al usuario y llamamos a nuestras dos funciones para completar nuestros controles. Listo, los juegos estan hechos!

Haz que los botones funcionen!

¿Recuerdas el código que habíamos escrito en nuestro índice.js archivo para adjuntar el controlador de eventos a nuestros botones? Se veía de esta manera:

	$('#createDB').hacer clic(función (mi) {
		e.preventDefault();
		createTables();
	});

	$('#exportDB').hacer clic(función (mi) {
		e.preventDefault();

	});

	$('#emptyDB').hacer clic(función (mi) {
		e.preventDefault();
                dropTables();
	});

	$(«#importDB»).hacer clic(función (mi) {
		e.preventDefault();

	});

Ahora tenemos que agregar una llamada a exportCopia de seguridad() y importCopia de seguridad() funciones para que este bloque de código se vea ligeramente diferente:

	$('#createDB').hacer clic(función (mi) {
		e.preventDefault();
		createTables();
	});

	$('#exportDB').hacer clic(función (mi) {
		e.preventDefault();
		exportCopia de seguridad(falso);
	});

	$('#emptyDB').hacer clic(función (mi) {
		e.preventDefault();
		dropTables();
	});

	$(«#importDB»).hacer clic(función (mi) {
		e.preventDefault();
		importCopia de seguridad(falso);
	});

Te muestro como todo índice.js el archivo debería verse tan lejos:

era aplicación = {
	inicializar: función () {
		document.addEventListener('Deviceready', this.onDeviceReady.bind(esta), falso);
	},
	onDeviceReady: función () {
		this.receivedEvent('Deviceready');
	},
	recibidoEvento: función (carné de identidad) {
		var parentElement = document.getElementById(carné de identidad);
		var listeningElement = parentElement.querySelector('.escuchando');
		var receivedElement = parentElement.querySelector('.recibido');

		listeningElement.setAttribute('estilo', 'monitor:ninguna;');
		receivedElement.setAttribute('estilo', 'monitor:bloquear;');

		consola.log('Evento recibido: ' + carné de identidad);
	}
};

app.initialize();

var db = window.openDatabase("dropbox_test", "1.0", "Prueba de importación / exportación de proceso de datos con Dropbox", 200000);

función createCountryTable() {
	db.transaction(función (Tx) {
		tx.executeSql("DROP TABLE SI EXISTE países");
		tx.executeSql("CREAR TABLA SI NO EXISTE países (ID AUTOINCREMENTO DE LLAVE PRIMARIA INTEGER, país INTEGER, código TEXT)", [], paísCreadoÉxito, countryCreatedError);
		tx.executeSql("INSERTAR EN países (carné de identidad, país, código) VALORES (1, 'Afganistán', 'DE'),(2, «Albania», 'ALABAMA'),(3, 'Argelia', 'DZ'),(4, 'Andorra', 'ANUNCIO'),(5, «Angola», 'PARA'),(6, 'Antigua y Barbuda', «AG»),(7, 'Argentina', 'CON'),(8, 'Armenia', 'SOY'),(9, 'Australia', 'PARA'),(10, «Austria», 'AT'),	(11, 'Azerbaiyán', 'AZ'),(12, «Bahamas, El', 'BS'),(13, 'Bahréin', 'BH'),(14, 'Bangladesh', 'BD'),(15, 'Barbados', 'BB'),(16, 'Bielorrusia', 'POR'),(17, 'Bélgica', 'SER'),(18, 'Belice', 'BZ'),	(19, 'Benín', 'BJ'),(20, 'Bután', 'BT'),(21, 'Bolivia', 'BO'),(22, 'Bosnia y Herzegovina', 'LICENCIADO EN LETRAS'),(23, «Botsuana», 'BW'),(24, 'Brasil', 'BR'),(25, 'Brunéi', 'BN'),(26, «Bulgaria», 'BG'),(27, «Burkina Faso», 'BF'),(28, «Burundi», 'CON UN'),(29, 'Camboya', 'KH'),(30, 'Camerún', 'CM'),(31, 'Canadá', 'ESE'),(32, 'Cabo Verde', 'CV'),(33, 'República Centroafricana', 'CF'),(34, 'Chad', 'TD'),(35, 'Chile', 'CL'),(36, 'Porcelana, República Popular de, «CN»),(37, 'Colombia', 'CO'),(38, 'Comoras', 'KM'),(39, Congo, (Congo ? Kinshasa)', 'CD'),(40, Congo, (Congo ? Brazzaville)', 'CG'),(41, 'Costa Rica', 'CR'),	(42, 'Costa de Marfil (Costa de Marfil)', 'ALLÍ'),	(43, 'Croacia', 'HORA'),	(44, 'Cuba', 'CON'),	(45, 'Chipre', 'CY'),	(46, 'República Checa', 'CZ'),(47, 'Dinamarca', 'DK'),	(48, «Yibuti», 'DJ'),	(49, «Dominica», 'DM'),	(50, 'República Dominicana', 'HACER'),	(51, 'Ecuador', 'CE'),	(52, 'Egipto', 'P.EJ'),	(53, 'El Salvador', 'SV'),	(54, 'Guinea Ecuatorial', 'GQ'),	(55, 'Eritrea', 'ES'),	(56, «Estonia», 'SÍ'),	(57, 'Etiopía', 'Y'),	(58, 'Fiyi', 'FJ'),	(59, 'Finlandia', 'SER'),	(60, 'Francia', 'FR'),	(61, 'Gabón', 'GEORGIA'),(62, «Gambia, El', 'GM'),(63, «Georgia», 'DAR'),(64, 'Alemania', 'DE'),	(65, 'Ghana', 'GH'),	(66, 'Grecia', 'GRAMO'),	(67, 'Granada', 'GD'),	(68, 'Guatemala', 'GT'),	(69, 'Guinea', 'GN'),	(70, «Guinea-Bissau», 'GW'),	(71, 'Guayana', 'GY'),	(72, 'Haití', 'HT'),	(73, 'Honduras', 'HN'),	(74, 'Hungría', 'HU'),	(75, 'Islandia', 'ES'),	(76, 'India', 'EN'),	(77, «Indonesia», 'IDENTIFICACIÓN'),	(78, 'Irán', 'IR'),	(79, 'Irak', 'IQ'),	(80, 'Irlanda', 'ES DECIR'),	(81, 'Israel', 'LOS'),	(82, 'Italia', 'ESO'),(83, 'Jamaica', 'JM'),	(84, 'Japón', 'JP'),	(85, 'Jordán', 'YA'),	(86, 'Kazajstán', 'KZ'),	(87, 'Kenia', 'KE'),	(88, 'Kiribati', 'KI'),	(89, 'Corea, Norte', 'KP'),	(90, 'Corea, Sur', 'KR'),	(91, 'Kuwait', 'KW'),(92, 'Kirguistán', 'KG'),	(93, 'Laos', 'LA'),	(94, 'Letonia', «VI»),	(95, 'Líbano', 'LB'),	(96, 'Lesoto', 'LS'),	(97, 'Liberia', 'LR'),	(98, 'Libia', 'LY'),	(99, «Liechtenstein», 'EN EL'),	(100, 'Lituania', 'LT'),	(101, 'Luxemburgo', 'LU'),	(102, 'Macedonia', 'MK'),	(103, «Madagascar», 'MG'),	(104, 'Malaui', 'MW'),	(105, 'Malasia', 'MI'),	(106, 'Maldivas', 'MV'),	(107, 'Malí', 'ML'),	(108, «Malta», 'MONTE'),	(109, 'Islas Marshall', 'MH'),	(110, «Mauritania», 'SEÑOR'),	(111, 'Mauricio', 'MU'),	(112, 'México', 'MX'),	(113, 'Micronesia', 'FM'),	(114, 'Moldavia', 'MARYLAND'),	(115, 'Mónaco', 'MC'),	(116, «Mongolia», 'MINNESOTA'),	(117, «Montenegro», 'YO'),	(118, 'Marruecos', 'MAMÁ'),	(119, «Mozambique», 'MZ'),	(120, Myanmar (Birmania)', 'MM'),	(121, «Namibia», 'N / A'),	(122, 'Nauru', 'NO'),	(123, 'Nepal', 'P.EJ'),	(124, 'Países Bajos', «NL»),	(125, 'Nueva Zelanda', 'NUEVA ZELANDA'),	(126, 'Nicaragua', 'NI'),	(127, 'Níger', 'NACIÓ'),	(128, 'Nigeria', 'NG'),	(129, 'Noruega', 'NO'),	(130, 'Omán', 'SI'),	(131, 'Pakistán', 'PAQUETE'),	(132, 'Palau', 'PW'),	(133, 'Panamá', 'PENSILVANIA'),	(134, 'Papúa Nueva Guinea', 'PG'),	(135, 'Paraguay', 'PY'),	(136, 'Perú', 'SOBRE'),	(137, 'Filipinas', 'PH'),	(138, 'Polonia', 'PL'),	(139, «Portugal», 'PT'),	(140, 'Katar', 'Control de calidad'),	(141, 'Rumania', 'RO'),	(142, 'Rusia', 'RU'),	(143, 'Ruanda', 'RW'),	(144, 'Saint Kitts y Nevis', 'KN'),	(145, 'Santa Lucía', 'LC'),	(146, 'San Vicente y las Granadinas', 'USTED'),	(147, 'Samoa', 'WS'),	(148, 'San Marino', 'SM'),	(149, 'Santo Tomé y Príncipe', 'S T'),	(150, 'Arabia Saudita', 'PARA'),	(151, 'Senegal', 'SN'),	(152, 'Serbia', 'RS'),	(153, «Seychelles», 'CAROLINA DEL SUR'),	(154, 'Sierra Leona', 'SL'),	(155, 'Singapur', «SG»),	(156, 'Eslovaquia', 'SK'),	(157, 'Eslovenia', 'Y'),	(158, 'Islas Salomón', 'SB'),	(159, 'Somalia', 'ASI QUE'),	(160, 'Sudáfrica', 'POR'),	(161, 'España', 'ES'),	(162, «Sri Lanka», 'PÁGINA'),	(163, 'Sudán', 'DAKOTA DEL SUR'),	(164, 'Surinam', 'SR'),	(165, 'Swazilandia', 'SZ'),	(166, 'Suecia', 'SE'),	(167, 'Suiza', 'CH'),	(168, 'Siria', 'SU'),	(169, 'Tayikistán', 'TJ'),	(170, 'Tanzania', 'TZ'),	(171, 'Tailandia', 'TH'),	(172, «Timor-Leste (Timor Oriental)', 'TL'),	(173, 'Ir', 'TG'),	(174, 'Tonga', 'PARA'),	(175, 'Trinidad y Tobago', 'TT'),	(176, 'Túnez', 'TENNESSE'),	(177, 'Pavo', 'TR'),	(178, 'Turkmenistán', 'TM'),	(179, 'Tuvalu', 'TELEVISOR'),	(180, 'Uganda', 'UG'),	(181, 'Ucrania', 'UA'),	(182, 'Emiratos Árabes Unidos', 'AE'),	(183, 'Reino Unido', 'GB'),	(184, 'Estados Unidos', 'NOSOTROS'),	(185, 'Uruguay', 'U'),	(186, 'Uzbekistán', 'PARA'),	(187, Vanuatu, 'VISTO'),	(188, 'Ciudad del Vaticano', 'VIRGINIA'),	(189, 'Venezuela', 'Y'),	(190, 'Vietnam', 'VN'),	(191, 'Yemen', 'S.M'),	(192, «Zambia», 'ZM'),	(193, 'Zimbabue', 'ZW'),	(194, 'Abjasia', 'DAR'),	(195, 'Porcelana, Republica de (Taiwán)', 'TW'),	(196, 'Nagorno-Karabaj', 'AZ'),	(197, 'El norte de Chipre', 'CY'),	(198, Pridnestrovie (Transnistria)', 'MARYLAND'),	(199, 'Somalilandia', 'ASI QUE'),	(200, 'Osetia del Sur', 'DAR'),	(201, 'Islas Ashmore y Cartier', 'PARA'),	(202, 'Isla de Navidad', 'CX'),	(203, «Cocos (Keeling) Islas ', 'CC'),	(204, 'Islas del Mar de Coral', 'PARA'),	(205, 'Isla Heard e Islas McDonald', 'HM'),	(206, 'Isla Norfolk', 'NF'),	(207, 'Nueva Caledonia', 'CAROLINA DEL NORTE'),	(208, 'Polinesia francés', 'PF'),	(209, 'Mayotte', 'YT'),	(210, 'San Bartolomé', 'GP'),	(211, 'San Martín', 'GP'),	(212, 'San Pedro y Miquelón', 'PM'),	(213, 'Wallis y Futuna', 'WF'),	(214, 'Tierras Australes y Antárticas Francesas', 'TF'),	(215, 'Isla Clipperton', 'PF'),	(216, 'Isla Bouvet', 'BV'),	(217, 'Islas Cook', 'CK'),	(218, 'Niue', 'NO'),	(219, 'Tokelau', 'CC.TT.'),	(220, 'Guernsey', 'GG'),	(221, 'Isla del hombre', 'SOY'),	(222, 'Jersey', 'JE'),	(223, 'Anguila', 'AL'),	(224, 'Islas Bermudas', 'BM'),	(225, 'Territorio Británico del Océano Índico', 'I'),	(226, 'Áreas de base soberana británica', ''),	(227, 'Islas Vírgenes Británicas', 'VG'),	(228, 'Islas Caimán', 'KENTUCKY'),	(229, 'Islas Malvinas (Islas Malvinas)', 'FK'),	(230, 'Gibraltar', 'DAR'),	(231, 'Montserrat', 'SRA'),	(232, 'Islas Pitcairn', 'PN'),	(233, 'Santa Elena', 'SH'),	(234, Georgia del Sur & Islas Sandwich del Sur, 'GS'),	(235, 'Islas Turcas y Caicos', 'TC'),	(236, 'Islas Marianas del Norte', 'MP'),	(237, 'Puerto Rico', 'Relaciones públicas'),	(238, 'Samoa Americana', 'COMO'),	(239, 'Isla Baker', 'A'),	(240, 'Guam', 'GU'),	(241, 'Isla Howland', 'A'),	(242, 'Isla Jarvis', 'A'),	(243, 'Atolón Johnston', 'A'),	(244, 'Arrecife Kingman', 'A'),	(245, 'Islas Midway', 'A'),	(246, 'Isla de Navassa', 'A'),	(247, 'Atolón de Palmyra', 'A'),	(248, 'NOSOTROS. Islas Virgenes', 'NOSOTROS'),	(249, 'Isla Wake', 'A'),	(250, 'Hong Kong', 'HK'),	(251, 'Macao', 'MES'),	(252, 'Islas Faroe', 'FO'),	(253, 'Groenlandia', 'GL'),	(254, 'Guayana Francesa', 'GF'),	(255, 'Guadalupe', 'GP'),	(256, 'Martinica', 'SQM'),	(257, 'Reunión', 'RE'),	(258, 'Una tierra', 'HACHA'),	(259, 'Aruba', 'AW'),	(260, 'Antillas Holandesas', 'UN'),	(261, 'Svalbard', 'SJ'),	(262, 'Ascensión', 'C.A'),	(263, 'Tristán da Cunha', 'EJÉRCITO DE RESERVA'),	(268, 'Territorio Antártico Australiano', 'AQ'),	(269, 'Dependencia de Ross', 'AQ'),	(270, 'Isla Pedro I', 'AQ'),	(271, 'Tierra de la Reina Maud', 'AQ'),	(272, 'Territorio Antártico Británico', 'AQ');", [], countryFilledSuccess, countryFilledError);
		función countryCreatedSuccess() {
			consola.log('Tabla de países creada correctamente!');
		}
		function countryCreatedError(Tx, error) {
			consola.log(mensaje de error);
		}
		función countryFilledSuccess() {
			consola.log('Tabla de países completada correctamente!');
			loadPaíses();
		}
		function countryFilledError(Tx, error) {
			consola.log(mensaje de error);
		}

	});
}

función createUsersTable() {
	db.transaction(función (Tx) {
		tx.executeSql("DROP TABLE SI EXISTE usuarios");
		tx.executeSql("CREAR TABLA SI NO EXISTE usuarios (ID AUTOINCREMENTO DE LLAVE PRIMARIA INTEGER, first_name TEXTO, last_name TEXTO, email_address TEXTO, TEXTO del país)", [], userCreatedSuccess, userCreatedError);
		tx.executeSql("INSERT INTO usuarios (carné de identidad, primer nombre, apellido, dirección de correo electrónico, país) VALORES (1, 'Juan', 'Gama', «john.doe@email.com», 'ESTADOS UNIDOS'), (2, 'Miguel', 'Olivares', 'miguel.olivares.Doe@email.es', 'España'), (3, 'Franz', 'Kuttermeyer', 'frankut@email.de', 'Alemania'), (4, 'Marianne', 'Jolie', 'mariannejolie@email.fr', 'Francia')", [], userFilledSuccess, userFilledError);
		función userCreatedSuccess() {
			consola.log('Tabla de usuarios creada correctamente!');
		}
		función userCreatedError(Tx, error) {
			consola.log(mensaje de error);
		}
		función userFilledSuccess() {
			consola.log('Tabla de usuarios completada correctamente!');
			loadUsers();
		}
		función userFilledError(Tx, error) {
			consola.log(mensaje de error);
		}
	});
}

función createTables() {
	createCountryTable();
	createUsersTable();
}

función dropCountriesTable() {
	db.transaction(función (Tx) {
		tx.executeSql("DROP TABLE SI EXISTE países", [], dropPaíses Éxito, dropCountriesError);
		función dropCountriesSuccess() {
			consola.log('Tabla de países eliminada con éxito!');
			loadPaíses();
		}
		función dropCountriesError(Tx, error) {
			consola.log(mensaje de error);
		}
	});
}

función dropUsersTable() {
	db.transaction(función (Tx) {
		tx.executeSql("DROP TABLE SI EXISTE usuarios", [], dropUsersSuccess, dropUsersError);
		función dropUsersSuccess() {
			consola.log('Tabla de usuarios eliminada correctamente!');
			loadUsers();
		}
		función dropUsersError(Tx, error) {
			consola.log(mensaje de error);
		}
	});
}
función dropTables() {
	dropUsersTable();
	dropCountriesTable();
}

función loadCountries() {
	var qry = "SELECCIONAR ID, país de países";
	db.transaction(función (Tx) {
		tx.executeSql(qry, [], querySuccess, queryError);
		función querySuccess(Tx, datos) {
			$('seleccionar # países').niños().retirar();
			var paises = {};
			por (var i = 0; yo < data.rows.length; yo ++) {
				$('seleccionar # países').adjuntar('<valor de la opción ="' + data.rows[yo].carné de identidad + '">' + data.rows[yo].país + '</opción>');
			}
		}
		función queryError(transacción, error) {
			consola.log('Query errorHandler' + mensaje de error + 'en consulta' + qry);
			//usamos la función de devolución de llamada de error para vaciar los controles de la página   
			$('seleccionar # países').niños().retirar();
			$('seleccionar # países').adjuntar('<opción>No se encontraron datos de países!</opción>');
		}
	});
}

función loadUsers() {
	var qry = "SELECCIONE first_name, apellido, dirección de correo electrónico, país de los usuarios";
	db.transaction(función (Tx) {
		tx.executeSql(qry, [], querySuccess, queryError);
		función querySuccess(Tx, datos) {
			$('#usuarios').niños().retirar();
			por (var i = 0; yo < data.rows.length; yo ++) {
				$('#usuarios').adjuntar('<= Li class"desplegable">'
						+ data.rows[yo].primer nombre
						+ ''
						+ data.rows[yo].apellido
						+ '<= Ul class"submenú"><en>'
						+ data.rows[yo].dirección de correo electrónico
						+ '</en><en>'
						+ data.rows[yo].país
						+ '</en></la></en>');
			}
		}
		función queryError(transacción, error) {
			consola.log('Query errorHandler' + mensaje de error + 'en consulta' + qry);
			//usamos la función de devolución de llamada de error para vaciar los controles de la página   
			$('#usuarios').niños().retirar();
			$('#usuarios').adjuntar('<opción>No se encontraron datos de usuario!</opción>');
		}
	});
}

función exportBackup() {
	var successFn = función (.sql) {
		window.resolveLocalFileSystemURL(cordova.file.dataDirectory, función (dirEntry) {
			dirEntry.getDirectory('/ dropboxTestBackup', {crear: cierto}, función (dirEntry) {
				dirEntry.getFile('dropboxTestBackup.sql', {crear: cierto}, función (fileEntry) {
					alerta("El archivo " + fileEntry.name + 'se ha creado en el siguiente directorio: Android / data / com.example.dropboxTest / files / dropboxTestBackup / ');
					writeFile(fileEntry, .sql);
				});
			}, onErrorCreateFile);
		}, onErrorCreateDir);
	};
	cordova.plugins.sqlitePorter.exportDbToSql(.db, {
		successFn: successFn
	});
}

función onErrorCreateFile(mi) {
	consola.log('Error al crear el archivo: ' + mi);
}

función onErrorCreateDir(mi) {
	consola.log('Error al crear el directorio: ' + mi);
}

función writeFile(fileEntry, dataObj) {
	// Crear un objeto FileWriter para nuestro FileEntry.
	fileEntry.createWriter(función (fileWriter (Escritor de archivos)) {
		fileWriter.onwriteend = función () {
			consola.log("Escritura exitosa de archivos...");
			readFile(fileEntry);
		};
		fileWriter.write(dataObj);
	}, onErrorWriteFile);
}

función onErrorWriteFile(mi) {
	consola.log('Error al escribir el archivo: ' + e.toString());
}

función readFile(fileEntry) {
	fileEntry.file(función (archivo) {
		var reader = nuevo FileReader();
		reader.onloadend = función () {
			consola.log("Lectura correcta del archivo: " + fileEntry.fullPath + " - contenido: " + this.result);
			return this.result;
		};
		reader.readAsText(archivo);
	}, onErrorReadFile);
}

función onErrorReadFile(mi) {
	consola.log('Error al leer el archivo: ' + mi);
}

función importBackup(desdeDropbox) {
	var rutaToArchivo = cordova.archivo.datosDirectorio + '/dropboxTestBackup/dropboxTestBackup.sql';
	window.resolveLocalFileSystemURL(pathToFile, función (fileEntry) {
		fileEntry.file(función (archivo) {
			var reader = nuevo FileReader();

			reader.onloadend = función (mi) {
				var successFn = función () {
					alerta('Base de datos restaurada con éxito!');
					loadPaíses();
					loadUsers();
				};
				cordova.plugins.sqlitePorter.importSqlToDb(.db, this.result, {
					successFn: successFn
				});
			};
			reader.readAsText(archivo);
		}, onErrorLoadFile);
	}, onErrorLoadFs);
}

función onErrorLoadFile(mi){
	consola.log('Error al leer el archivo: ' + e.toString());
}

función onErrorLoadFs(mi) {
	consola.log('Error al cargar el sistema de archivos: ' + mi);
}

$(documento).Listo(función () {
	
	loadPaíses();
	loadUsers();
	
	$('#createDB').hacer clic(función (mi) {
		e.preventDefault();
		createTables();
	});

	$('#exportDB').hacer clic(función (mi) {
		e.preventDefault();
		exportCopia de seguridad(falso);
	});

	$('#emptyDB').hacer clic(función (mi) {
		e.preventDefault();
		dropTables();
	});

	$(«#importDB»).hacer clic(función (mi) {
		e.preventDefault();
		importCopia de seguridad(falso);
	});
	
	$('#usuarios').en('hacer clic', 'li.dropdown', función (mi) {
		e.preventDefault();
		consola.log($(esta).texto());
		elementos var = $(esta).hermanos().encontrar('ul.submenú');
		artículos cada uno(función () {
			Si ($(esta).es(':visible')) {
				$(esta).deslizar hacia arriba('lento');
			}
		});
		$(esta).encontrar('ul.submenú').slideToggle();
	});	
	
});

 

Ahora podemos exportar nuestra base de datos a un archivo local y si es necesario, restaurarlo desde el archivo de respaldo. Solo ejecuta la aplicación, y sigue estos pasos para probar la aplicación:

  1. Grifo Crear base de datos para crear la base de datos (if you didn’t do it yet)
  2. Exportarlo tocando Exportar base de datos botón
  3. Ahora toca Base de datos vacía botón para eliminar todos sus datos
  4. y luego toque Importar base de datos botón para ver sus datos en vivo de nuevo!

Excelente, No es?

Pero queremos asegurarnos de que nuestro usuario pueda recuperar sus datos incluso si ha desinstalado nuestra aplicación en un momento de trastorno mental y luego, una vez que ha vuelto a la razón, lo ha reinstalado. Así que tenemos que ofrecerle la opción de guardar su archivo de copia de seguridad en algún host externo.. Lo adivinas? sí, Dropbox! Y este será el argumento de la próxima, capítulo final de este tutorial.

 


 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *