How to initialize database with default values when installing application for the first time

482 views
Skip to first unread message

Mart-Indrek Süld

unread,
Mar 13, 2014, 8:50:09 AM3/13/14
to mobile-c...@googlegroups.com
I'm having hard time to figure out how to fill database with default values when installing application for the first time. 

Database is used locally and no external connection should be required. That leaves me with two options:
  1. pre-defined database - Is it reasonable to replace the database? If so, what are the best techniques? Which program should i use to create pre-defined database (Like "SQLite Expert" for ordinary SQL databases) ?
    manager.replaceDatabase(arg0, arg1, arg2); //how to use it properly?
  2. data file - open the data file and go through each line?
Data i want to insert looks like this:
[
    {
        "_id": 1,
        "name": "Financial",
        "description": "Collection of financial books",
        "Books": {
            "Rich dad poor dad": {
"description":"How to save and invest money"
},
"How to stay rich":{
"description":"What you should know about money"
}
        }
    },
    {
        "_id": 2,
        "name": "Comics",
        "description": "Collection of comic books",
        "Books": {
            "Superman": {
"description":"Undercover journalist"
},
"Green hornet":{
"description":"Green guys in a suit"
}
        }
    }
]

Would really appreciate, if someone would help me! :)

Thank you!

Jens Alfke

unread,
Mar 13, 2014, 10:39:14 AM3/13/14
to mobile-c...@googlegroups.com

On Mar 13, 2014, at 5:50 AM, Mart-Indrek Süld <mi....@gmail.com> wrote:

I'm having hard time to figure out how to fill database with default values when installing application for the first time. 

You should use this CBLManager method:

/** Replaces or installs a database from a file.
    This is primarily used to install a canned database on first launch of an app, in which case you should first check .exists to avoid replacing the database if it exists already. The canned database would have been copied into your app bundle at build time.
    @param databaseName  The name of the database to replace.
    @param databasePath  Path of the database file that should replace it.
    @param attachmentsPath  Path of the associated attachments directory, or nil if there are no attachments.
    @param outError  If an error occurs, it will be stored into this parameter on return.
    @return  YES if the database was copied, NO if an error occurred. */
- (BOOL) replaceDatabaseNamed: (NSString*)databaseName
             withDatabaseFile: (NSString*)databasePath
              withAttachments: (NSString*)attachmentsPath
                        error: (NSError**)outError;

Which program should i use to create pre-defined database (Like "SQLite Expert" for ordinary SQL databases) ?

Use your own app, if that’s reasonable — first run the app with a blank database and add the data you need, then go into the app’s Application Support/CouchbaseLite/ directory and copy the “foo.cblite” and “foo attachments” into your source directory, and set Xcode to copy them into your app bundle as resources so you can find them at launch time.

If that isn’t practical, you can run the LiteServ app that comes with the beta release; it’s a simple wrapper around Couchbase Lite that runs a REST API on port 59840. You can then use any kind of script you want to PUT documents to the database.

—Jens

Mart-Indrek Süld

unread,
Mar 13, 2014, 11:15:49 AM3/13/14
to mobile-c...@googlegroups.com
Thanks a lot for the reply, Jens.

But do you know how to do the initialization on Android? I'm developing on Eclipse and followed a tutorial in ...

As soon as i started to use CBLite on my own application, i ran into problems.

I'm trying to achieve something like this, but i get exception:
// create a new database
Database database = null;
try {
database = manager.getExistingDatabase(dbname); //if this line works, then db already exists
} catch (CouchbaseLiteException e) {
database = manager.getDatabase(dbname); //exception thrown, need to initialize db
//in addition to creating the db:
//insertDefaultValuesIntoDB();
//replaceDBWithExistingDB();
}

Filling the data inside the code/app isn't reasonable, since the data contains about 100 items and therefore it's reasonable to use data file or replace database itself.
Message has been deleted

Andrew Reslan

unread,
Mar 13, 2014, 7:11:16 PM3/13/14
to mobile-c...@googlegroups.com
If you have stored a canned db in your applications assets folder called "source.cblite", you might try something like the following.

If the db "replaced" does not already exist, It first writes the canned db to local file storage, in this case the cache folder, then uses it to overwrite the  "replaced" db.


```java

private void setupDB() {

   Database db = null;

   try {

        db = manager.getExistingDatabase("replaced");

        if(db == null) {
        
            InputStream dbStream = getAssets().open("source.cblite");

            File tempDB = new File(getCacheDir(), "\"temp.cblite\"");

            FileOutputStream tempOutput = new FileOutputStream(tempDB);

            copyFile(dbStream, tempOutput);

            manager.replaceDatabase("replaced", tempDB, null);
        }
    }
    catch(Exception e)
    {
           //
    }
    catch(IOException ioex)
    {
        //
    }
}

private void copyFile(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while((read = in.read(buffer)) != -1){
            out.write(buffer, 0, read);
        }
    }

```

Mart-Indrek Süld

unread,
Mar 14, 2014, 6:15:49 AM3/14/14
to mobile-c...@googlegroups.com
Thank you Andrew!

Seems to be exactly what i'm looking for. :)

But how do i create pre-defined ("source.cblite") database (which program)? I googled for it and found no answers. I'm using Windows, but only thing i found was Couchbase Lite Viewer (for iOS, no Windows).

Andrew Reslan

unread,
Mar 14, 2014, 8:11:34 AM3/14/14
to mobile-c...@googlegroups.com
As Jens suggested the easiest way is probably to generate it on a device or in an emulator.

You could write a simple App that generates the initial document set then exits, another option would be to write a JUnit test.

Once the code has run, you can then retrieve the .cblite database file from the device or emulator using Android ADB command.

If you use a JUnit test from the couchbase-lite-android project, your DB will be created in the following folder on the device/emulator.

/data/data/com.couchbase.cblite.test/files/test


You should then see the following files/folders:


cblite-test

cblite-test.cblite

cblite-test.cblite-journal


cblite-test - contains an attachments subfolder, which will contain attachment binaries if you created any docs with attachments. You will need to copy these off the device/emulator if you have docs in your DB with attachments.


cblite-test.cblite - this is the DB file that your code created, you need to copy this off of the device/emulator and embed it in your App as an asset.


cblite-test.cblite-journal - journal file for your DB, this is not required


On MAC OS X, for a standard install of the latest android sdk, the adb command is located at:

/Applications/Android Studio.app/sdk/platform-tools


The following commands, taken from MAC OS X, can be used to copy files from the device/emulator to your dev machine (commands are in bold):

$ ./adb shell
shell@android:/ $ su
shell@android:/ # cp /data/data/your.package.name/databases/<your_database>.cblite /mnt/shell/emulated/0/Download/<your_database>.cblite
shell@android:/ # exit
shell@android:/ $ exit
localuser:~ localhost$ adb pull /mnt/shell/emulated/0/Download/<your_database>.cblite ~/<your_database>.cblite

What it does is:
1. Connects to the emulator
2. Requests superuser permissions
3. Copies the file that is only available to superuser to a public directory (Downloads in this case)
4. Pulls the file from public folder (Downloads) to your local machine home directory.

Reply all
Reply to author
Forward
0 new messages