GreenDao Paso2 – DBManager impl

Buenas!

En esta entrada vamos a ver cómo crear nuestro gestor para la base de datos y cómo usarlo. Y con esto daremos por terminada la primera versión de guardar los datos en una base de datos cifrada.

DBManager

Lo primero que hacemos es crearnos un nuevo paquete en nuestro proyecto para tenerlo todo bien separado y creamos una interfaz con los métodos que consideremos útiles. Nosotros hemos elegido estos:

public interface DBManager {

    void closeDbConnections();
    void dropDb();

    boolean insertToken(DBToken token);

    boolean updateToken(DBToken token);

    List<DBToken> listTokens();

    DBToken getToken(Long tokenid);

    boolean deleteToken();
}

Son los típicos métodos de CRUD.

A continuación nos crearemos una nueva clase que implemente esta interfaz.

Hemos planteado la clase para que funcione con Singleton, ya que no necesitamos más que una única instancia del gestor de la db.

En el siguiente fragmento de código, veremos cómo  inicializar el “Helper” de nuestra base de datos encriptada que permitirá abrir nuestra DB en modo lectura o escritura.

public DBManagerImpl(final Context context) {
    this.context = context;
    mHelper = new DaoMaster.EncryptedDevOpenHelper(this.context, "spotifyClientDB");
    completedOperations = new CopyOnWriteArrayList<>();
}

public static DBManagerImpl getInstance(Context context) {
    if (instance == null) {
        instance = new DBManagerImpl(context);
    }
    return instance;
}

De los métodos de nuestra interfaz tenemos closeDbConnections() y dropDb() que uno cierra/limpia e iguala a nulo todas las instancias de la base de datos, como podemos ver en el repositorio y dropDb que abre la db en modo escritura, borra todas las tablas, y las vuelve a crear vacías con todos sus elementos borrados:

@Override
public void dropDb() {
    try {
        openWritableDb();
        DaoMaster.dropAllTables(database, true); // drops all tables
        mHelper.onCreate(database);              // creates the tables
        asyncSession.deleteAll(DBToken.class);    // clear all elements from a table
    } catch (Exception e) {
        e.printStackTrace();
    }
}

InsertToken

En este método, insertamos el token a la DB después de validar que no venga nulo. Para ello abrimos la DB en modo escritura y con el DAO (Data Access Object) que nos devuelve la sesión de nuestra DB, insertamos el token en ella.

@Override
public boolean insertToken(DBToken token) {
    try{
        if(token != null){
            openWritableDb();
            DBTokenDao tokenDao = daoSession.getDBTokenDao();
            tokenDao.insert(token);
            daoSession.clear();
            database.close();
            return true;
        }
        return false;
    } catch (Exception e){
        e.printStackTrace();
    }
    return false;
}

GetToken – ListTokens

Para leer los tokens de la DB hemos creado 2 métodos, uno que funciona mandando un id a la db y te devuelve un token concreto y otro que te devuelve todos los tokens.

Esta funcionalidad es ahora mismo absurda, porque la idea de la aplicación es que solo tenga 1 token en todo momento, por lo que en un futuro será eliminada, era para probar.

Del código no hay mucho que explicar, funciona de manera similar al insertar, solo que se hace un “loadAll()” en el Dao para obtener todos los datos.

@Override
public List<DBToken> listTokens() {
    List<DBToken> tokens = null;
    try{
        openReadableDb();
        DBTokenDao tokenDao = daoSession.getDBTokenDao();
        tokens = tokenDao.loadAll();

        daoSession.clear();
        database.close();
    } catch (Exception e){
        e.printStackTrace();
    }

    if(tokens != null)
        return tokens;
    return null;
}

@Override
public DBToken getToken(Long tokenid) {
    ...
    token = tokenDao.load(tokenid);
    ...
    return token;
}

Update

Para actualizar un valor de la db, seguimos la misma idea y en el daoSession (no en el Dao de la tabla) haremos un update con el objeto directamente.

daoSession.update(token);

DeleteToken

Siguiendo la misma idea, hemos hecho el método deleteToken obteniendo el Dao y haciendo un:

tokenDao.deleteAll();

Para borrar todos los tokens de la db. Si quisiéramoas borrar un único token, usaríamos ”

deleteByKey(long tokenid)

OpenReadableDb / OpenWritableDb

Para abrir una conexión con la db en modo lectura o escritura, solo tenemos que indicarle la forma de la que queremos abrirla y la contraseña de la DB cifrada (ahora mismo está puesta tal cuál en la aplicación porque estamos en un entorno de prueba. Si fuera a publicarse, habría que encontrar la manera de obtener una clave del tipo SHA1 para cifrar la DB correctamente y guardar esa clave en algún entorno seguro).

public void openReadableDb() throws SQLiteException {
    database = mHelper.getReadableDatabase("contraseñahipersecreta");
    openDb();
}

public void openWritableDb() throws SQLiteException {
    database = mHelper.getWritableDatabase("contraseñahipersecreta");
    openDb();
}

private void openDb(){
    daoMaster = new DaoMaster(database);
    daoSession = daoMaster.newSession();
    asyncSession = daoSession.startAsyncSession();
    asyncSession.setListener(this);
}

El asyncSession del que no hemos hablado, es otra interfaz que implementa la clase para realizar las acciones de modo asíncrono.

¿Cómo usarlo?

Para usarlo, es tan fácil como obtener la instancia del gestor de la base de datos en una actividad:

databaseManager = DBManagerImpl.getInstance(this);

Y para insertar un dato, echando una mirada a la siguiente entrada ya que voy a insertar el token de mi usuario de Spotify, inicializamos la variable token de los modelos generador previamente con GreenDao y si el token no es nulo ni vacío, lo insertamos en la base de datos haciendo una llamada a “insertToken()” y ya está.

DBToken token = new DBToken();
boolean todoOk = false;
if(response.getAccessToken() != null && !response.getAccessToken().isEmpty()){
    databaseManager.deleteToken();
    token.setTokenvalue(response.getAccessToken());
    todoOk = databaseManager.insertToken(token);
}

Para leer el token que hemos insertado, simplemente tendríamos que usar el método get o listTokens que hemos hecho antes.

List<DBToken> dbtokens = databaseManager.listTokens();

 

Con esto podéis ver cómo hemos hecho una base de datos encriptada (con una contraseña horrible y que NO debéis usar ya que  incluir la contraseña en la propia app es inseguro) y hemos visto cómo usarla completamente y con facilidad gracias a la librería GreenDao que nos lo ha puesto bastante fácil para hacerlo. ¡Eh! ¡Y sin escribir nada de código SQL!

Recordad que todo el código está también en el repositorio de GitHub.

Un saludo 😉

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s