Open/Use two sqlite databases concurrrently
<p>I'm trying to use two database files at once, and I thought it was possible, but I seem to be running into an issue where only the last one opened is available for use.  </p>

<p>if my code is arranged as follows it works:</p>

<pre><code>private void populateTabs(int TabShown) {
    // Get specific setup info from database into cursor
    setupDBHelper = new DBAdapter(this);
    setupDBHelper.open(DBAdapter.MAIN_DATABASE_NAME, DBAdapter.MAIN_DATABASE_VERSION);

    setupCursor = setupDBHelper.fetchSetup(RowId);
    this.startManagingCursor(setupCursor);
    setupCursor.moveToFirst();

    offsetDBHelper = new DBAdapter(this);
    offsetDBHelper.open(DBAdapter.OFFSET_DATABASE_NAME, DBAdapter.OFFSET_DATABASE_VERSION);

    offsetCursor = offsetDBHelper.fetchOffset(setupCursor.getString(setupCursor
            .getColumnIndex(DBAdapter.SETUP_PART)));
    this.startManagingCursor(offsetCursor);
    offsetCursor.moveToFirst();
}
</code></pre>

<p>However, if I rearrange the code as follows I get a "no such table: xxxx" when it tries to run fetchSetup(), which indicates to me it's trying to use the wrogn db even though I've pointed it to the correct one (or so it seems to me):</p>

<pre><code>private void populateTabs(int TabShown) {
    // Get specific setup info from database into cursor
    setupDBHelper = new DBAdapter(this);
    setupDBHelper.open(DBAdapter.MAIN_DATABASE_NAME, DBAdapter.MAIN_DATABASE_VERSION);

    offsetDBHelper = new DBAdapter(this);
    offsetDBHelper.open(DBAdapter.OFFSET_DATABASE_NAME, DBAdapter.OFFSET_DATABASE_VERSION);

    setupCursor = setupDBHelper.fetchSetup(RowId);
    this.startManagingCursor(setupCursor);
    setupCursor.moveToFirst();      

    offsetCursor = offsetDBHelper.fetchOffset(setupCursor.getString(setupCursor
            .getColumnIndex(DBAdapter.SETUP_PART)));
    this.startManagingCursor(offsetCursor);
    offsetCursor.moveToFirst();
</code></pre>

<p>}</p>

<p>Not a big deal except I have several other methods that reference one or the other database specifically and I won't be controlling what order those methods are used, nor do I wish to open and close the db each time.  I'd rather open each once and close when completely done.  </p>

<p>Am I missing something obvious?  Is it possible to do?</p>

<p>If you need other bits of my code let me know, I'll be happy to post it.</p>

<p><strong>EDIT</strong></p>

<p>Relevant bits of my DBAdapter:</p>

<pre><code>public class DBAdapter {
// DB info
public static final String MAIN_DATABASE_NAME = "Bowers";
public static final String OFFSET_DATABASE_NAME = "BowersOffset";
public static final String NOTES_DATABASE_NAME = "Notes";
public static final String GMCODES_DATABASE_NAME = "GMCodes";
public static final int MAIN_DATABASE_VERSION = 1;
public static final int OFFSET_DATABASE_VERSION = 1;
public static final int NOTES_DATABASE_VERSION = 1;
public static final int GMCODES_DATABASE_VERSION = 1;

public static String MAIN_DB_PATH = "/data/data/cdc.workshopapps.BowersMfgHelper/databases/";

// database control
private DatabaseHelper mDbHelper;
private static SQLiteDatabase mDb;
private static Context mCtx;

private static class DatabaseHelper extends SQLiteOpenHelper {
    DatabaseHelper(Context context, String dbname, int dbversion) {
        super(context, dbname, null, dbversion);
        if (checkDataBase(dbname)) {
            openDataBase(dbname);
        } else {
            try {
                this.getReadableDatabase();
                copyDataBase(dbname);
                this.close();
                openDataBase(dbname);
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
            Toast.makeText(context,
                    "Initial " + dbname + " database has been created",
                    Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

public DBAdapter(Context ctx) {
    DBAdapter.mCtx = ctx;
}

public DBAdapter open(String dbname, int dbversion) throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx, dbname, dbversion);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

public void close() {
    mDbHelper.close();
}

private static void copyDataBase(String dbname) throws IOException {
    InputStream myInput = mCtx.getAssets().open(dbname);
    String outFileName = MAIN_DB_PATH + dbname;
    OutputStream myOutput = new FileOutputStream(outFileName);

    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) &gt; 0) {
        myOutput.write(buffer, 0, length);
    }

    myOutput.flush();
    myOutput.close();
    myInput.close();
}

private static boolean checkDataBase(String dbname) {
    SQLiteDatabase checkDB = null;
    boolean exist = false;
    try {
        String db = MAIN_DB_PATH + dbname;
        checkDB = SQLiteDatabase.openDatabase(db, null,
                SQLiteDatabase.OPEN_READONLY);
    } catch (SQLiteException e) {
        Log.v("db log", "database does't exist");
    }

    if (checkDB != null) {
        exist = true;
        checkDB.close();
    }
    return exist;
}

public static void openDataBase(String dbname) throws SQLException {
    String dbPath = MAIN_DB_PATH + dbname;
    mDb = SQLiteDatabase.openDatabase(dbPath, null,
            SQLiteDatabase.OPEN_READWRITE);
}

//  public Cursor fetchOffset(String part) throws SQLException {
//      Cursor mCursor = mDb.query(true, OFFSET_TABLE, new String[] {
//              OFFSET_ROWID, OFFSET_PART, SETUP_D1, SETUP_D2, SETUP_D3,
//              SETUP_D4, SETUP_D5, SETUP_D6, SETUP_D7, SETUP_D8, SETUP_D9,
//              SETUP_D10, SETUP_D11, SETUP_D12, SETUP_D13, SETUP_D14,
//              SETUP_D15, SETUP_D16, SETUP_D17, SETUP_D18, SETUP_D19,
//              SETUP_D20, SETUP_G54, SETUP_G55, SETUP_G56, SETUP_G57,
//              SETUP_G58, SETUP_G59, SETUP_G110, SETUP_G111, SETUP_G112,
//              SETUP_G113, SETUP_G114, SETUP_G115, SETUP_G116, SETUP_G117,
//              SETUP_G118, SETUP_G119, SETUP_G120, SETUP_G121, SETUP_G122,
//              SETUP_G123 }, OFFSET_PART + "= '" + part + "'", null, null,
//              null, null, null);
//      if (mCursor != null) {
//          mCursor.moveToFirst();
//      }
//      return mCursor;
//  }

public Cursor fetchSetup(Long rowId) throws SQLException {
    Cursor mCursor = mDb.query(true, SETUP_TABLE, new String[] {
            SETUP_ROWID, SETUP_PART, SETUP_PGM1, SETUP_PGM2, SETUP_PGM3,
            SETUP_T1, SETUP_T2, SETUP_T3, SETUP_T4, SETUP_T5, SETUP_T6,
            SETUP_T7, SETUP_T8, SETUP_T9, SETUP_T10, SETUP_T11, SETUP_T12,
            SETUP_T13, SETUP_T14, SETUP_T15, SETUP_T16, SETUP_T17,
            SETUP_T18, SETUP_T19, SETUP_T20, SETUP_KIT, SETUP_FIXTURE1,
            SETUP_FIXTURE2, SETUP_FIXTURELOC, SETUP_VISE, SETUP_JAWS,
            SETUP_JAWLOC, SETUP_NOTES, SETUP_MISC1, SETUP_MISC2,
            SETUP_MISC3, SETUP_D1, SETUP_D2, SETUP_D3, SETUP_D4, SETUP_D5,
            SETUP_D6, SETUP_D7, SETUP_D8, SETUP_D9, SETUP_D10, SETUP_D11,
            SETUP_D12, SETUP_D13, SETUP_D14, SETUP_D15, SETUP_D16,
            SETUP_D17, SETUP_D18, SETUP_D19, SETUP_D20, SETUP_G54,
            SETUP_G55, SETUP_G56, SETUP_G57, SETUP_G58, SETUP_G59,
            SETUP_G110, SETUP_G111, SETUP_G112, SETUP_G113, SETUP_G114,
            SETUP_G115, SETUP_G116, SETUP_G117, SETUP_G118, SETUP_G119,
            SETUP_G120, SETUP_G121, SETUP_G122, SETUP_G123 }, TOOL_ROWID
            + "=" + rowId, null, null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}
}
</code></pre>
