Using more than 1 Database in Greendao with 2 different Schemas - Android
Asked Answered
N

2

6

I have 2 databases in the project, one of them created when I open the app, the other is provided with the assets.

When DaoSession is generated the DaoSession is created for all models.

also the Schema in the gradle file is used for both databases

How can I differentiate between the 2 databases and their schemas ?

Nachison answered 19/2, 2017 at 15:42 Comment(0)
N
1

For Greendao Version 3, it is not possible to have more than 1 schema.

github.com/greenrobot/greenDAO/issues/356

As they wrote on their website also:

Note that multiple schemas are currently not supported when using the Gradle plugin . For the time being, continue to use your generator project.

They have added this feature yet to the new GreenDao.

Nachison answered 9/3, 2017 at 6:55 Comment(0)
K
5

You need to create two different classes which extends org.greenrobot.greendao.database.DatabaseOpenHelper. These two different classes DevOpenHelperForDatabase1 and DevOpenHelperForDatabase2 will handle db realted I/o. It is versy easy to understand from the below code to create two different database with same and different schema or table or entities:

public class App extends Application {
private DaoSessionForDatabase1 mDaoSessionForDatabase1;
private DaoSessionForDatabase2 mDaoSessionForDatabase2;

@Override
public void onCreate() {
    super.onCreate();

    //Create Doa session for database1
    DevOpenHelperForDatabase1 devOpenHelperForDatabase1 = new DevOpenHelperForDatabase1(this,
        "database1-db");
    Database databse1 =  devOpenHelperForDatabase1.getWritableDb();
    mDaoSessionForDatabase1 = new DaoMasterForDatabase1(databse1).newSession();

    //Create Doa session for database2
    DevOpenHelperForDatabase2 devOpenHelperForDatabase2 = new DevOpenHelperForDatabase2(this,
        "database2-db");
    Database databse2 =  devOpenHelperForDatabase2.getWritableDb();
    mDaoSessionForDatabase2 = new DaoMasterForDatabase2(databse2).newSession();
}

public DaoSessionForDatabase1 getDaoSessioForDatabase1() {
    return mDaoSessionForDatabase1;
}

public DaoSessionForDatabase2 getDaoSessioForDatabase2() {
    return mDaoSessionForDatabase2;
}
}

You can access same and different schema or table or entities as bellow from Activity as an example:

// get the Schema1 DAO for Database1
DaoSessionForDatabase1 daoSessionForDatabase1 = ((App)    getApplication()).getDaoSessioForDatabase1();
Schema1Dao schema1Dao = daoSessionForDatabase1.getSchema1Dao();

// get the Schema2 DAO for Database2
DaoSessionForDatabase2 daoSessionForDatabase2 = ((App)  getApplication()).getDaoSessioForDatabase2();
Schema2Dao schema2Dao = daoSessionForDatabase2.getSchema2Dao();

Update 2:: The above can be discarded but the approach will be the same. Update done based on the discussion in the comments below:

I made the changes in the example greenDAO -> examples

package org.greenrobot.greendao.example;

import android.app.Application;

import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.example.DaoMaster.DevOpenHelper;

public class App extends Application {
/** A flag to show how easily you can switch from standard SQLite to  the encrypted SQLCipher. */
public static final boolean ENCRYPTED = true;

private DaoSession daoSession;

private DaoSession daoSession1;

@Override
public void onCreate() {
    super.onCreate();

    DevOpenHelper helper = new DevOpenHelper(this, ENCRYPTED ? "notes-db-encrypted" : "notes-db");
    Database db = ENCRYPTED ? helper.getEncryptedWritableDb("super-secret") : helper.getWritableDb();
    daoSession = new DaoMaster(db).newSession();


    DevOpenHelper helper1 = new DevOpenHelper(this, "notes1-db");
    Database db1 = helper1.getWritableDb();
    daoSession1 = new DaoMaster(db1).newSession();
}

public DaoSession getDaoSession() {
    return daoSession;
}

public DaoSession getDaoSession1() {
    return daoSession1;
}
}

Now make the following chnages in NoteActivity.java

//Add below class members
private static boolean switchDbBetweenOneAndTwo = false;
private NoteDao noteDao2;
private Query<Note> notesQuery2;

//In on craete add the following as the last statement after   notesQuery = noteDao.queryBuilder().orderAsc(NoteDao.Properties.Text).build();
@Override
public void onCreate(Bundle savedInstanceState) {
......
Log.d("Database 1", "notesQuery.list()="+notesQuery.list().toString());

    // get the note DAO for Database2
    DaoSession daoSessionForDb2 = ((App) getApplication()).getDaoSession1();
    noteDao2 = daoSessionForDb2.getNoteDao();

    // query all notes, sorted a-z by their text
    notesQuery2 = noteDao2.queryBuilder().orderAsc(NoteDao.Properties.Text).build();
    Log.d("Database 2", "notesQuery2.list()="+notesQuery2.list().toString());
    updateNotes();
}

//Replace updateNotes as
private void updateNotes() {
    List<Note> notes = notesQuery.list();
    List<Note> notes2 = notesQuery2.list();
    notes.addAll(notes2);
    notesAdapter.setNotes(notes);
}

//Replace addNote as
private void addNote() {
    String noteText = editText.getText().toString();
    editText.setText("");

    final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
    String comment = "Added on " + df.format(new Date());

    Note note = new Note();
    note.setText(noteText);
    note.setComment(comment);
    note.setDate(new Date());
    note.setType(NoteType.TEXT);
    if(!switchDbBetweenOneAndTwo){
        note.setText(noteText + " In database 1");
        noteDao.insert(note);
    }
    else {
        note.setText(noteText + " In database 2");
        noteDao2.insert(note);
    }
    Log.d("DaoExample", "Inserted new note, ID: " + note.getId());
    switchDbBetweenOneAndTwo = true;
    updateNotes();
}

I made no changes in gradle file or added anything as it dosen't make any sense to me.

Kenosis answered 6/3, 2017 at 11:3 Comment(12)
DaoSessionForDatabase auto generated files. We cannot name it or change its name by ourselves. Did you test this code? is it really working? or you are expecting the way it might be ?Nachison
I did the same for blackberry some year back using different dao. I am expecting the wau it might be based on the experience.Kenosis
unfortunately, this is not the case in GreenDao, the schema is set in the gradle file. I think it will be different.Nachison
In which gradle app.gradle or project level gradle? Then give me some time to revert. ThanksKenosis
@It is working. I will update the example in 15 mins. Let's see what you have to say :-)Kenosis
@Nachison Check now?Kenosis
:( they dont support multi schema on version 3 : github.com/greenrobot/greenDAO/issues/356 anyway i will test the code you postedNachison
The code that I have posted will work. Because it's from their repo only. :-)Kenosis
in your case, i dont know how you got 2 DaoMaster, but in my situation I always get only 1 DaoMaster ?Nachison
In actual the logic is very simple. Database is just a file in a file system. You can create n number of files within the private package scope in case of android. So I am pretty sure that I have solved your problem.Kenosis
You are absolutely right. I already use many databases in my project. However I use GreenDao to make it ORM. Unfortunately, the owner of the library mentioned that they dont support multi schema (multi databases) yet in their new version which i am already using. Thank you so much for your effortNachison
Appreciated, do let me know if I am missing anything. Thank-youKenosis
N
1

For Greendao Version 3, it is not possible to have more than 1 schema.

github.com/greenrobot/greenDAO/issues/356

As they wrote on their website also:

Note that multiple schemas are currently not supported when using the Gradle plugin . For the time being, continue to use your generator project.

They have added this feature yet to the new GreenDao.

Nachison answered 9/3, 2017 at 6:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.