Android Sugar ORM with Existing DB & Custom File Path
Asked Answered
O

3

8

I'm perfectly able to use Sugar ORM using provided examples.

In my usecase I download a SQLite DB from the server (ETL load for it is in millions of records so has to be done server side). The download saves to a custom path on internal storage.

In my case I do not need dynamic DB creation based on POCOs.

Is it possible to use Sugar ORM with pre-existing SQLite DB, pointing to a custom path, provided if all POCO classes fields match the table structure?

Orran answered 15/6, 2014 at 0:34 Comment(2)
we are really in need of such a toolArteriotomy
@Orran did you find any solution ?Shanda
H
4
  1. First of all, I am not comfortable with the idea that Sugar extends the app class. What if I have other tasks need to be carried out before app start?! So let's extend SugarApp with our own AppClass then register the appClass name in manifest. Also, this is the right place to init db the first time I believe.

    public class MyAppStartClass extends SugarApp {
    
    @Override
    public final void onCreate() {
        init();
        super.onCreate();
    }
    
    private void init() {
        initDB();
    }
    
    private void initDB() {
        try {
            if (!doesDatabaseExist(this, consts.dbPath)) {
                Context context = getApplicationContext();
                SQLiteDatabase db = context.openOrCreateDatabase(consts.dbName, context.MODE_PRIVATE, null);
                db.close();
                InputStream dbInput = getApplicationContext().getAssets().open(consts.dbName);
                String outFileName = consts.dbPath;
                OutputStream dbOutput = new FileOutputStream(outFileName);
                try {
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = dbInput.read(buffer)) > 0) {
                        dbOutput.write(buffer, 0, length);
                    }
                } finally {
                    dbOutput.flush();
                    dbOutput.close();
                    dbInput.close();
                }
            }
        } catch (Exception e) {
            e.toString();
        }
    }
    
    private boolean doesDatabaseExist(ContextWrapper context, String dbName)       {
        File dbFile = context.getDatabasePath(dbName);
        return dbFile.exists();
    }
    }
    
  2. Manifest: android:name="com.myPackageName.MyAppStartClass"

  3. Make sure you create an empty db first, if you don't you'll get an error from FileOutputStream() and dbPath = /data/data/com.myPackageName/databases/myDb.db

    SQLiteDatabase db = context.openOrCreateDatabase(consts.dbName, context.MODE_PRIVATE, null);

    db.close();

  4. Make sure your existing db schema has a primary key column ID. Oh yeah! Sugar only sees ID as primary key to retrieve data.

  5. If you want to use existing tables, do NOT specify T when you extend SugarRecord AND you have to add Sugar as a module and your project depends on it!

    public class Book extends SugarRecord {
      String title;
      String edition;
    
      public Book(){
      }
    
      public Book(String title, String edition){
        this.title = title;
        this.edition = edition;
      }
    }
    

6.If you want to use existing tables. Be aware that Sugar looks for UPPERCASE column names so if your existing table column names are lowercase you will never get any existing data out of it!

7.That leads me to a reluctant conclusion: Sugar is great if your start db from scratch and use it to generate db and tables for you. But not so when you have already had an existing db with data in it.

Halfmoon answered 24/5, 2015 at 3:13 Comment(1)
For #1 look at the code of SugarApp.onCreate(), you can call SugarContext.init(this); in your own code instead of extending.Lassiter
T
3

The solution I found, was by putting your db file inside of assets folder. Instead of reading a .csv file to create a .db file ( when you start the proper activity) firstly try to check if the .db file is in /data/data/file.db, if it isn't, copy it from your assets folder to that path. With the next code you will be able to make all:

protected void copyDataBase() throws IOException {

        //Open your local db as the input stream
        InputStream myInput = getApplicationContext().getAssets().open("file.db");

        // Path to the just created empty db
        String outFileName = "/data/data/com.yourpackagename/databases/" + "file.db";

        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        //transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer))>0){
            myOutput.write(buffer, 0, length);
        }

        //Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();

    }
    protected boolean checkDataBase(){

        SQLiteDatabase checkDB = null;

        try{
            String myPath = "/data/data/com.yourpackage/databases/" + "file.db";
            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;
    }
Tremble answered 30/4, 2015 at 16:27 Comment(0)
N
0

I haven't tried it yet. Though, if you could copy your database file to /data/data//db_name.db location and use the same db_name & db version in the sugar config in manifest, it should just pick it up.

Natation answered 17/6, 2014 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.