<commit_before>package com.eaglesakura.android.db;

import com.eaglesakura.lambda.Action1Throwable;
import com.eaglesakura.lambda.Action2Throwable;
import com.eaglesakura.util.ThrowableRunnable;
import com.eaglesakura.util.ThrowableRunner;

import android.content.Context;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.io.Closeable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.AbstractDaoMaster;
import de.greenrobot.dao.AbstractDaoSession;
import de.greenrobot.dao.Property;
import de.greenrobot.dao.query.CloseableListIterator;

public abstract class DaoDatabase<SessionClass extends AbstractDaoSession> implements Closeable {

    protected final Context context;

    protected final Class<? extends AbstractDaoMaster> daoMasterClass;

    protected AbstractDaoMaster daoMaster;

    protected SessionClass session;

    final private Object refsLock = new Object();

    private int refs = 0;

    /**
     * 新規に生成する
     */
    public DaoDatabase(Context context, Class<? extends AbstractDaoMaster> daoMasterClass) {
        this.context = context.getApplicationContext();
        this.daoMasterClass = daoMasterClass;
    }

    /**
     * DaoMasterを指定して生成する
     */
    public DaoDatabase(Context context, AbstractDaoMaster daoMaster) {
        this.context = context.getApplicationContext();
        this.daoMaster = daoMaster;
        this.daoMasterClass = daoMaster.getClass();
    }

    public Context getContext() {
        return context;
    }

    protected abstract SQLiteOpenHelper createHelper();

    @SuppressWarnings("unchecked")
    public void open(boolean readOnly) {
        synchronized (refsLock) {
            if (daoMaster == null) {
                SQLiteOpenHelper helper = createHelper();
                SQLiteDatabase db = readOnly ? helper.getReadableDatabase() : helper.getWritableDatabase();

                try {
                    Constructor<? extends AbstractDaoMaster> constructor = daoMasterClass.getConstructor(SQLiteDatabase.class);
                    daoMaster = constructor.newInstance(db);
                    session = (SessionClass) daoMaster.newSession();
                } catch (Exception e) {
                    throw new IllegalStateException(e);
                }
            }
            ++refs;

            // 正常終了した
            return;
        }
    }

    public void openReadOnly() {
        open(true);
    }

    public void openWritable() {
        open(false);
    }

    /**
     * Sessionを取得する
     * queryを投げるのに使う。
     */
    public SessionClass getSession() {
        return session;
    }

    /**
     * 戻り値と例外を許容してトランザクション実行を行う
     */
    public <RetType, ErrType extends Throwable> RetType runInTx(ThrowableRunnable<RetType, ErrType> runnable) throws ErrType {
        ThrowableRunner<RetType, ErrType> runner = new ThrowableRunner<>(runnable);
        session.runInTx(runner);
        return runner.getOrThrow();
    }

    /**
     * イテレータで読み込めるオブジェクトに対して処理を行う
     */<commit_msg>戻り値を指定したOpenメソッドを追加<commit_after>package com.eaglesakura.android.db;

import com.eaglesakura.lambda.Action1Throwable;
import com.eaglesakura.lambda.Action2Throwable;
import com.eaglesakura.util.ThrowableRunnable;
import com.eaglesakura.util.ThrowableRunner;

import android.content.Context;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.io.Closeable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.AbstractDaoMaster;
import de.greenrobot.dao.AbstractDaoSession;
import de.greenrobot.dao.Property;
import de.greenrobot.dao.query.CloseableListIterator;

public abstract class DaoDatabase<SessionClass extends AbstractDaoSession> implements Closeable {

    protected final Context context;

    protected final Class<? extends AbstractDaoMaster> daoMasterClass;

    protected AbstractDaoMaster daoMaster;

    protected SessionClass session;

    final private Object refsLock = new Object();

    private int refs = 0;

    /**
     * 新規に生成する
     */
    public DaoDatabase(Context context, Class<? extends AbstractDaoMaster> daoMasterClass) {
        this.context = context.getApplicationContext();
        this.daoMasterClass = daoMasterClass;
    }

    /**
     * DaoMasterを指定して生成する
     */
    public DaoDatabase(Context context, AbstractDaoMaster daoMaster) {
        this.context = context.getApplicationContext();
        this.daoMaster = daoMaster;
        this.daoMasterClass = daoMaster.getClass();
    }

    public Context getContext() {
        return context;
    }

    protected abstract SQLiteOpenHelper createHelper();

    @SuppressWarnings("unchecked")
    public void open(boolean readOnly) {
        synchronized (refsLock) {
            if (daoMaster == null) {
                SQLiteOpenHelper helper = createHelper();
                SQLiteDatabase db = readOnly ? helper.getReadableDatabase() : helper.getWritableDatabase();

                try {
                    Constructor<? extends AbstractDaoMaster> constructor = daoMasterClass.getConstructor(SQLiteDatabase.class);
                    daoMaster = constructor.newInstance(db);
                    session = (SessionClass) daoMaster.newSession();
                } catch (Exception e) {
                    throw new IllegalStateException(e);
                }
            }
            ++refs;

            // 正常終了した
            return;
        }
    }

    public <T extends DaoDatabase<SessionClass>> T openReadOnly(Class<T> clazz) {
        openReadOnly();
        return (T) this;
    }

    public <T extends DaoDatabase<SessionClass>> T openWritable(Class<T> clazz) {
        openWritable();
        return (T) this;
    }

    public void openReadOnly() {
        open(true);
    }

    public void openWritable() {
        open(false);
    }

    /**
     * Sessionを取得する
     * queryを投げるのに使う。
     */
    public SessionClass getSession() {
        return session;
    }

    /**
     * 戻り値と例外を許容してトランザクション実行を行う
     */
    public <RetType, ErrType extends Throwable> RetType runInTx(ThrowableRunnable<RetType, ErrType> runnable) throws ErrType {
        ThrowableRunner<RetType, ErrType> runner = new ThrowableRunner<>(runnable);
        session.runInTx(runner);
        return runner.getOrThrow();
    }

    /**
     * イテレータで読み込めるオブジェクトに対して処理を行う
     */
{'fraction_non_alphanumeric': 0.08860759493670886, 'fraction_numerical': 0.0009041591320072332, 'mean_word_length': 2.794739851343625, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3869070', 'n_tokens_mistral': 1982, 'n_tokens_neox': 1966, 'n_words': 372}