Dividir o partir una Base de Datos Grande en trozos de 1Mb. Instalar Ubuntu (Linux) paso a paso y usar el comando Split

Este para mi va a ser mi mejor tutorial, mi buque insignia! ;p ahora a ver como sale... (espero que no sea una MIERDA) este tuto se va a centrar en instalar Linux y partir o trocear la Base de Datos que hiciste en el tema anterior si te salió mayor de 1Mb, para ello usaremos un comando que se llama Split.

Aunque esto ya lo conté en la lección anterior, voy a recordar el motivo de porque necesitamos dividir la Base de Datos en partes de 1Mb... pues el tema es que existe una limitación en Android para copiar ficheros de mas de 1Mb desde el directorio assets o raw, si intentamos copiar una Base de Datos con menos de 1Mb no hay ningún problema, copiamos la base de datos al proyecto y ejecutamos el código en la clase SQLiteOpenHelper y LISTO!, con mas de 1Mb nos dara un error, por lo que tendremos que dividir o partir el fichero de Base de Datos en fragmentos o partes de 1Mb, para luego recomponerla en nuestra aplicación, este proceso de Partir o Dividir la base de datos es lo "complicado", tendremos que usar un comando "split" que solo esta en sistemas operativos Linux, por eso es la complejidad de este asunto, pero bueno, no te preocupes!! porque vamos a ver paso a paso como descargar linux e instalarla en una máquina virtual, todo es GRATIS, así. que no te preocupes!!

Para hacer todo esto, tendremos que instalar Ubuntu (una versión de Linux), el motivo es que Linux es un muy buen sistema operativo para gestionar bases de datos, y por tanto, posee comandos especiales y que no tienen otros sistemas operativos como windows para gestionarlas, vamos que.. esto no es un capricho mío porque me mola mas Linux, esto es porque Windows no hace esto ni de coña, y tampoco he encontrado ningún programa gratuito que lo haga, así que.. me temo que no queda otra que instalar Linux.

Antes de que sigas leyendo.. no te preocupes de nada! todo es gratis y fácil de bajar, es decir te voy a pasar los links de sus sitios oficiales para que lo descargues sin ningún problema, se que la primera impresión cuando se lee esto es pensar.. ufff que follon, voy a buscar otra solución... pues no, te digo que yo instale Linux por primera vez por esto, así que no soy un defensor de Linux, si sigues esta guía te será muy fácil, lo vas a ver PASO A PASO, y además GRATIS, así que.. ¡sigue leyendo soldado! ;p.

La siguiente otra gran duda que se que estarás pensando... "¿donde coño instalo en ubuntu este de los cojones?" bueno este es mi gran reto, soy consciente que lo que voy a explicarte no es fácil de digerir así de primeras, y es un poco lioso al principio captar la filosofía, pero estoy seguro que lo vas a pillar!! (por lo menos yo lo voy a intentar) no se si habrás oído habar de las Máquinas Virtuales, o la Visualización. Pues bien, esto es un software que "emula" un equipo físico, y podemos usarlo como un PC normal dentro de lo que ya tienes, es decir, no tendrás que formatear tu equipo ni hacer nada raro... así que el resultado de todo esto, será que tendrás dentro de una ventana de tu PC, otro ordenador al que instalaremos Linux! mola eh? bueno, pos comenzamos ya!!

Requerimientos previos antes de seguir este tutorial (descarga estas dos cosas):

 Ubuntu Linux. Es un ISO que usaremos para instalar Linux, seguramente te sonara que, Linux es GRATUITO, de echo Android corre bajo Linux, así que, en cierto modo, ya lo estabas usando! ;P no tendrás problemas para descargarlo en su pagina oficial: http://www.ubuntu.com/download/desktop

 VMware Player. Es el software que usaremos para la virtualizacion, es un instalable que bajaremos de la pagina de VMware, descargate la versión "Player" que es la GRATUITA, es posible que para descargarte el programa, te pida registrarte. Una vez descargado, instalala con todas las opciones por defecto, tendrás un icono en el escritorio. http://www.vmware.com/products/player/overview.html

 

Paso 1: Instalar Ubuntu en una Máquina Virtual.

Cuando iniciemos la aplicación, veras su consola, en ella se administran las máquinas virtuales que tengamos (Arrancar la Máquina Virtual, añadir mas RAM, cambiar discos duros..) en tu caso no tendrás ninguna, así que directamente aparecerán las opciones que ves en la parte de la derecha, este software es muy muy practico, yo lo uso para testar sistemas operativos, o mantener algún programa mas antiguo sobre Windows XP que ya no funcionan bajo Windows 7 o 8... puedes crearte cuantas máquinas virtuales quieras, tendrás que configurar su Hardware (discos duros, RAM, usb, puertos com...) comencemos para el caso que nos ocupa, instalar Linux, así que pulsa sobre "Create a New Virtual Machine".

sqlite android

Al pulsar sobre crear una nueva Máquina Virtual, WMware Player te preguntara desde donde la quieres instalar, y tendrás 3 opciones, como en el paso previo, nos descargamos un ISO de Ubuntu, que es una imagen, tendremos que elegir la segunda opción "Instaler from disc image file (iso)" buscala con el botón browser y pulsa sobre Next.

sqlite, select

En este paso, seleccionamos el sistema operativo que vamos a instalar, y la versión, así VMware te sugiere en el siguiente paso el HDD que necesitas, RAM...

sqlite, select

En el siguiente paso, podemos seleccionar la capacidad del disco que tendrá la Máquina Virtual, esto dependerá del espacio libre que tenga tu ordenador, si vas sobrado dejalo así, si vas justo, pon 8Gb, deja la opción de que te haga Split, no me quiero enrollar mucho en esto, pero básicamente es para que te sea mas fácil moverla si la quisieras copiar a otro sitio.

sqlite, select

Aquí veras un resumen de lo que hemos hecho, y si le das al botón "customize Hardware..." podrás añadir o quitar hardware, modificar RAM... si te parece bien todo pulsa Finish! y veras arrancar la Máquina virtual.

sqlite, select

Como veras, se ve igual que una Máquina física de verdad, esto tiene su BIOS y todo, ahora arrancara la imagen ISO igual que si la hubieras quemado en un DVD de verdad.

sqlite, select

Pues nada, vamos a instalar Ubuntu, es muy fácil, es como instalar un windows, es poner idiomas, nombre y contraseña de la sesión, franja horaria y poco mas, el típico siguiente, siguiente, siguiente... como ves lo primero es seleccionar el idioma y pulsa sobre Instalar Ubuntu.

instalar ubuntu

Ahora vemos los requerimientos de Ubuntu, como ves dice que necesita al menos 4,8Gb, piensa ya que no estamos hablando del equipo físico, si no tocaste nada en los pasos previos, Ubuntu se esta instalando en un disco de 20Gb, en mi caso no detecta internet, pero es posible que a ti ya si, dejalo así y pulsa siguiente.

instalar ubuntu

Aquí selecciona la opción de Borrar disco e instalar Ubuntu, recuerda que esto es para la Máquina virtual, no tengas miedo!

instalar ubuntu

Simplemente selecciona tu franja horaria y pulsa continuar.

instalar ubuntu

Ya hemos terminado! ahora comenzara a copiar los ficheros necesarios para iniciar el sistema, puedo adelantarte que tarda poquito, yo acostumbrado a instalar windows me a sorprendido bastante la rapidez con la que se instala esto.

instalar ubuntu

Bueno, una vez instalado, pulsa sobre el botón de "inicio" para buscar la consola en Linux se llama Terminal, para poder ejecutar los comandos.

ejemplo comando split, linux

En la barra de búsqueda escribe la palabra "terminal" y en la lista que te aparece haz click en la aplicación "Terminal".

ejemplo comando split, linux

Bueno, ya tenemos el terminal para introducir el comando Split ahora lo que nos queda es coger la Base de Datos que creamos en la lección anterior y dividirla en ficheros de 1Mb, para ello usaremos un PenDrive USB para intercambiar ficheros entre nuestro ordenador fisico, que seguramente correra bajo windows y nuestra maquina virtual que corre bajo Linux.

ejemplo comando split, linux

Una vez tengas copiada la Base de datos en la memoria USB, ve a la barra de menu el VMware, pulsa sobre "Removable Devices" y busca en la lista tu dispositivo USB, despues selecciona la opcion "Connect (Disconect from host)".

ejemplo comando split, linux

Como ves, se te agregara la memoria USB en tu maquina virtual (Linux), y ya podremos dividir la base de datos, si instalas las WMware Tools (te aparecera un aviso debajo de la pantalla), podras arrastrar archivos entre la maquina fisica y la maquina virtual, y no necesitaras PenDrive, esto ya como tu quieras, el resultado es el mismo.

La manera de copiar archivos y arrastrarlos es muy parecido a windows, en mi caso, la memoria USB la he llamado "start" mi base de datos la he llamado "db_calc" la arrastro y la copio en la carpeta "Home", de esta forma en el Terminal no tendremos que movernos entre carpetas, por defecto, cuando entramos en el Terminal estaremos en esa carpeta.

ejemplo comando split, linux

Ya solo nos queda ejecutar el comando Split, un poco mas abajo te pongo la sintasis del comando, pero para este caso en concreto yo he utilizado exactamente esto:

split -b 1m calc_db nueva_

Fijate que el resultado del comando Split ha creado varios archivos de 1Mb con un sufijo _aa, _ab, _ac... esto lo crea solo el comando, por eso en el nombre de la nueva base de datos acabo con un guion bajo, para que no se junte ese sufijo con el nombre que elijas.

ejemplo comando split, linux

Bueno, pues ya hemos acabado, copia de nuevo todos los ficheros a la memoria USB para despues copiarlos al proyecto Android.

 

Síntesis comando Split


Sobre split:
Divide un fichero grande en trozos mas pequeños.

Syntax:
split -b n [k | m] [origen [nombre]] [destino [nombre]]

-b n. Divide los ficheros en trozos de n bytes in size.
-b n k. Divide un fichero en trozos n*1024 bytes in size.
-b n m. Divide un fichero en trozos de n*1048576 bytes in size.

Ejemplos:

split -b 1m nombre_db nuevoNombre_db

Divide el fichero "nombre_db" en ficheros de 1Mb con nombre "nuevoNombre" seguidos de un prefijo tipo aa, ab, ac, ad....

 

Paso 2: Recomponer el archivo de Base de Datos en la aplicacion Android en la clase SQLiteOpenHelper.

assests, androidAhora os voy a poner el codigo que use en mi app para recomponer el fichero de base de datos en mi aplicacion, basicamente es como la del tema anterior con algun ligero cambio.

El cambio mas significativo es la ubicacion de los ficheros resultantes de dividir la base de datos, en este caso los he puesto en la carpeta Raw dentro de recursos, en teoria es lo mismo que el assests, pero el ejemplo que vi y adapte en mi aplicacion estaba asi, y como sabeis el primer mandamiento de la informatica es:

si funciona... NO LO TOQUES!!

El resto de diferencias esta relacionado con la parte donde se recompone el fichero, pero basicamente es igual que el del tema anterior.

 

Codigo completo de mi aplicacion de la clase SQLiteOpenHelper.

package es.epinanab.calculadoraticket;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

public class BaseDeDatos extends SQLiteOpenHelper {

	public static String DB_PATH = "/data/data/es.epinanab.calculadoraticket/databases/";
	public static String DB_NAME = "db_calc";
	private SQLiteDatabase myDataBase;
	private final Context myContext;

	String sqlCreate = "CREATE TABLE restaurantes (_ID INTEGER PRIMARY KEY AUTOINCREMENT, nombre TEXT, lat DOUBLE, lon DOUBLE, direccion TEXT,	cp INTEGER, localidad TEXT, provincia TEXT, telefono INTEGER, tipo_comida TEXT, tipo_vale TEXT)";

	public BaseDeDatos(Context contexto, String nombre, CursorFactory factory,
			int version) {

		super(contexto, nombre, factory, version);
		this.myContext = contexto;
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// No se usa xq la copiamos
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// esto es para actualizar la db, no la usamos!
	}

	public void createDataBase() throws IOException {

		boolean dbExist = checkDataBase();

		if (dbExist) {
			// do nothing - database already exist
		} else {

			// By calling this method and empty database will be created into
			// the default system path
			// of your application so we are gonna be able to overwrite that
			// database with our database.
			this.getReadableDatabase();

			try {

				copyDataBase();

			} catch (IOException e) {

				throw new Error("Error copying database");

			}
		}

	}

	private boolean checkDataBase() {

		SQLiteDatabase checkDB = null;

		try {
			String myPath = DB_PATH + DB_NAME;
			checkDB = SQLiteDatabase.openDatabase(myPath, null,
					SQLiteDatabase.OPEN_READONLY);

		} catch (SQLiteException e) {
			// database does't exist yet.
		}

		if (checkDB != null) {

			checkDB.close();
		}

		return checkDB != null ? true : false;
	}

	public void openDataBase() throws SQLException {

		// Open the database
		String myPath = DB_PATH + DB_NAME;
		myDataBase = SQLiteDatabase.openDatabase(myPath, null,
				SQLiteDatabase.OPEN_READONLY);
		// myDataBase.close(); //esta la añado yo
	}

	@Override
	public synchronized void close() {

		if (myDataBase != null)
			myDataBase.close();

		super.close();
	}

	private void copyDataBase() throws IOException {

		OutputStream databaseOutputStream = new
		// FileOutputStream("/data/data/es.epinanab.calculadoraticket/databases/db_calc");
		FileOutputStream("" + DB_PATH + DB_NAME);
		InputStream databaseInputStream;

		byte[] buffer = new byte[1024];
		int length;
		
		//Comenzamos a recomponer el fichero
		databaseInputStream = myContext.getResources().openRawResource(
				R.raw.db_calc_aa);
		while ((length = databaseInputStream.read(buffer)) > 0) {
			databaseOutputStream.write(buffer);
		}
		databaseInputStream.close();

		databaseInputStream = myContext.getResources().openRawResource(
				R.raw.db_calc_ab);
		while ((length = databaseInputStream.read(buffer)) > 0) {
			databaseOutputStream.write(buffer);
		}
		databaseInputStream.close();

		databaseInputStream = myContext.getResources().openRawResource(
				R.raw.db_calc_ac);
		while ((length = databaseInputStream.read(buffer)) > 0) {
			databaseOutputStream.write(buffer);
		}
		databaseInputStream.close();

		databaseInputStream = myContext.getResources().openRawResource(
				R.raw.db_calc_ad);
		while ((length = databaseInputStream.read(buffer)) > 0) {
			databaseOutputStream.write(buffer);
		}
		databaseInputStream.close();

		databaseInputStream = myContext.getResources().openRawResource(
				R.raw.db_calc_ae);
		while ((length = databaseInputStream.read(buffer)) > 0) {
			databaseOutputStream.write(buffer);
		}
		databaseInputStream.close();

		databaseInputStream = myContext.getResources().openRawResource(
				R.raw.db_calc_af);
		while ((length = databaseInputStream.read(buffer)) > 0) {
			databaseOutputStream.write(buffer);
		}
		databaseInputStream.close();
		
		//cerramos el fichero
		databaseOutputStream.flush();
		databaseOutputStream.close();
	}

}

Paso 3: Poner el codigo en tu aplicacion con la que ejecutara el codigo que hemos creado en el paso 2.

El codigo que vas a ver a continuacion, deberas ponerlo solo la primera vez que intentes accedes a la base de datos por primera vez, yo te aconsejo que lo pongas seguido al OnCreate para que te asegures de que inicializas la base de datos antes de usarla mas adelante cuando te interese.

// Esto es para inicializar la BD
		BaseDeDatos db2 = new BaseDeDatos(this, DB_NAME, null, DB_VERSION);
		try {
			db2.createDataBase();
			db2.openDataBase();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			  

¿que os parece? no es complicado, como todo requiere practica y hacer varias pruebas, pero vamos si yo pude. ¡tu también! animo y si no te aclaras, pregunta en el foro.

Si te a gustado este sitio, por favor haz click en me gusta en Facebook, Google+, Tweeter... es el único precio que te pido por este trabajo! ;P. Compartiendo, ayudaras a otros a encontrar esta web! GRACIASSSS.