package com.github.florent37.rxandroidorm; import android.app.Application; import android.content.Context; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; import java.lang.reflect.Constructor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import io.reactivex.Observable; import io.reactivex.ObservableEmitter; import io.reactivex.ObservableOnSubscribe; import io.reactivex.annotations.NonNull; import io.reactivex.functions.Action; import io.reactivex.functions.Consumer; /** * Created by florentchampigny on 18/05/2016. */ public final class RxAndroidOrm { private static final String TAG = "RxAndroidOrm"; private static RxAndroidOrm INSTANCE; private SQLiteDatabase database; private SQLiteOpenHelper helper; private AtomicInteger usages = new AtomicInteger(0); private RxAndroidOrm() { } public static RxAndroidOrm getInstance() { if (INSTANCE == null) { INSTANCE = new RxAndroidOrm(); } return INSTANCE; } public static RxAndroidOrm onDestroy() { RxAndroidOrm rxAndroidOrm = getInstance(); rxAndroidOrm.close(); return rxAndroidOrm; } public static RxAndroidOrm onCreate(Application application) { RxAndroidOrm rxAndroidOrm = getInstance(); rxAndroidOrm.helper = rxAndroidOrm.findDatabaseHelper(application); return rxAndroidOrm; } public SQLiteDatabase getDatabase() { return database; } public RxAndroidOrm open() throws SQLException { if (helper != null) { database = helper.getWritableDatabase(); } return this; } public RxAndroidOrm close() { if (helper != null) { helper.close(); } return this; } private SQLiteOpenHelper findDatabaseHelper(Application application) { final String className = "com.github.florent37.rxandroidorm.DatabaseHelper"; try { Class<?> clazz = Class.forName(className); Constructor<?> constructor = clazz.getConstructor(Context.class); return (SQLiteOpenHelper) constructor.newInstance(application); } catch (Exception e) { Log.e(TAG, "cannot construct RxAndroidOrm", e); } return null; } public Observable<SQLiteDatabase> database() { return Observable .create(new ObservableOnSubscribe<SQLiteDatabase>() { @Override public void subscribe(ObservableEmitter<SQLiteDatabase> e) throws Exception { usages.incrementAndGet(); SQLiteDatabase database = RxAndroidOrm.getInstance().open().getDatabase(); e.onNext(database); e.onComplete(); } }) .doOnTerminate(new Action() { @Override public void run() throws Exception { Observable.timer(3, TimeUnit.SECONDS) .subscribe(new Consumer<Long>() { @Override public void accept(@NonNull Long aLong) throws Exception { final int count = usages.decrementAndGet(); if(count == 0) { RxAndroidOrm.getInstance().close(); } } }); } }); } }