Menyiapkan Database Menggunakan SQLite Database Browser

Dalam pembuatan app yang sesungguhnya, terkadang jauh lebih efisien membuat database pada saat merancang app daripada saat run-time. Misalnya, kita ingin membuat app untuk mencatat log koordinat dari semua tempat yang sudah kita datangi. Dalam hal ini, jauh lebih mudah membuat database saat proses pembuatan app dan menggunakannya saat run-time. 

Untuk membuat database SQLite, kita bisa menggunakan banyak tool gratis yang tersedia di internet. Salah satu tool semacam ini adalah SQLite Database Browser, dan tool ini tersedia untuk berbagai macam platform (http://sqlitebrowser.org/).

Setelah kita menginstal SQLite Database Browser, kita bisa membuat database secara visual seperti gambar di bawah ini. Semua proses interaksi dengan database bisa dilakukan secara langsung dan mudah.
Berinteraksi dengan Database SQLite
Menggunakan SQLiite Database Browser
Mem-Bundle Database dalam Package App

Latihan ini kita masih menggunakan kode yang sama dengan latihan-latihan sebelumnya tentang menyimpan dan berinteraksi data ke database.

1. Copy dan paste atau drag dan drop file database SQLite yang dibuat sebelumnya dengan SQLite Database Browser ke folder assets. Sebelumnya kita harus membuat folder assets di Android Studio di bawah folder app (root).
Catatan: nama file untuk file-file yang ditambahkan ke folder assets harus dalam huruf kecil, jadi nama file MyDB tidak valid, jadi harus diganti dengan mydb.
2. File class pembantu masih sama dengan kode sebelumnya, DBAdapter.java:
package com.example.bundlingdb;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DBAdapter { 
static final String KEY_ROWID = "_id";
static final String KEY_NAME = "name";
static final String KEY_EMAIL = "email";
static final String TAG = "DBAdapter";

static final String DATABASE_NAME = "MyDB";
static final String DATABASE_TABLE =" contacts";
static final int DATABASE_VERSION = 1;

static final String DATABASE_CREATE = "create table contacts (_id integer primary key autoincrement, "
+ "name text not null, email text not null);";

final Context context;

DatabaseHelper DBHelper;
SQLiteDatabase db;

public DBAdapter(Context ctx){
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}


private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME,null,DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(DATABASE_CREATE);
}
catch (SQLException sqle){
sqle.printStackTrace();
}
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG,"Upgrading database from version " + oldVersion + " to " + newVersion +
", which will destroy all old data");
db.execSQL("DROP TABLE IF EXIST contacts");
onCreate(db);
}
}

//--open database--
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}

//--close database--
public void close()
{
DBHelper.close();
}

//--insert a contact into database--
public long insertContact(String name, String email)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_EMAIL, email);
return db.insert(DATABASE_TABLE,null, initialValues);
}

//--delete particular contact--
public boolean deleteContact(long rowId) {
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}

//--retrieves all contacts--
public Cursor getAllContacts()
{
return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME, KEY_EMAIL}, null, null, null, null,null);
}

//--retrieves particular contact--
public Cursor getContact(long rowId) throws SQLException
{
Cursor mCursor = db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,KEY_NAME,KEY_EMAIL}, KEY_ROWID
+ "=" + rowId, null,null,null,null,null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}

//--updates a contact
public boolean updateContact(long rowId, String name, String email)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_EMAIL, email);
return db.update(DATABASE_TABLE,args, KEY_ROWID + "=" + rowId, null) > 0;
}
}
3. Modifikasi atau tambahkan kode yang dicetak tebal dalam file java: MainActivity.java
package com.example.bundlingdb;

import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast; 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

DBAdapter db = new DBAdapter(this);
try {
String destPath = "/data/data/" + getPackageName() + "/databases";
File f = new File(destPath);
if (!f.exists()){
f.mkdirs();
f.createNewFile();

//--copy db dari folder asset ke folder database
CopyDB(getBaseContext().getAssets().open("mydb"), new FileOutputStream(destPath + "/MyDB"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}


//--get all contacts
db.open();
Cursor c = db.getAllContacts();
if (c.moveToFirst())
{
do {
DisplayContact(c);
} while (c.moveToNext());
}
db.close();
}

public void CopyDB(InputStream inputStream, OutputStream outputStream) throws IOException {
//--copy 1K bytes at a time
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}


public void DisplayContact(Cursor c)
{
Toast.makeText(this, "id: "+c.getString(0)+ "\n" + "Name: " + c.getString(1)+ "\n"+
"Email: "+c.getString(2), Toast.LENGTH_LONG).show();
}
}

Jalankan di Android Studio emulator. Bila app kita berjalan, app akan men-copy file database mydb ke folder /data/data/com.example.bundlingdb/databases/ dengan nama MyDB.

Penjelasan

Pertama kita membuat method CopyDB() untuk men-copy file database dari satu lokasi ke lokasi lainnya:
public void CopyDB(InputStream inputStream, OutputStream outputStream) throws IOException {
//--copy 1K bytes at a time
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}
Catatan:
Dalam latihan ini kita menggunakan object 'InputStream' untuk membaca dari file sumber, dan kemudian menuliskannya ke file tujuan dengan menggunakan object 'OutputStream'.

Ketika 'activity' dibuat (onCreate()), kita men-copy file database yang ada di folder assets ke folder /data/data/com.example.bundlingdb/databases/ di perangkat Android (atau di emulator):
try {
String destPath = "/data/data/" + getPackageName() + "/databases";
File f = new File(destPath);
if (!f.exists()){
f.mkdirs();
f.createNewFile();

//--copy db dari folder asset ke folder database
CopyDB(getBaseContext().getAssets().open("mydb"), new FileOutputStream(destPath + "/MyDB"));

}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Kita men-copy file database hanya bila file tersebut tidak ada di folder tujuan. Bila kita tidak melakukan cek seperti ini, setiap kali 'activity' dibuat (onCreate()) kita akan menimpa file database dengan file yang ada di folder assets.

No comments: