All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nhaarman.ellie.query.ResultQueryBase Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2014 Michael Pardo
 * Copyright (C) 2014 Niek Haarman
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.nhaarman.ellie.query;

import android.database.Cursor;

import com.nhaarman.ellie.Ellie;
import com.nhaarman.ellie.Model;
import com.nhaarman.ellie.ModelRepository;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.Subscriber;

import static rx.Observable.OnSubscribe;

@SuppressWarnings("ParameterNameDiffersFromOverriddenParameter")
public abstract class ResultQueryBase extends ExecutableQueryBase implements ResultQuery {

    private Ellie mEllie;

    protected ResultQueryBase(final Query parent, final Class table) {
        super(parent, table);
        mEllie = parent.getEllie();
    }

    public static  List rawQuery(final Ellie ellie, final Class cls, final String sql, final String[] selectionArgs) {
        return processAndCloseCursor(ellie, cls, ellie.getDatabase().rawQuery(sql, selectionArgs));
    }

    public ResultQueryBase with(final Ellie ellie) {
        mEllie = ellie;
        return this;
    }

    @Override
    public  List fetch() {
        return (List) rawQuery(mEllie, mTable, getSql(), getArgs());
    }

    @Override
    public  T fetchSingle() {
        List results = (List) rawQuery(mEllie, mTable, getSql(), getArgs());
        if (!results.isEmpty()) {
            return results.get(0);
        }
        return null;
    }

    @Override
    public  T fetchValue(final Class type) {
        final Cursor cursor = mEllie.getDatabase().rawQuery(getSql(), getArgs());
        if (!cursor.moveToFirst()) {
            return null;
        }

        if (type.equals(Byte[].class) || type.equals(byte[].class)) {
            return (T) cursor.getBlob(0);
        }
        if (type.equals(double.class) || type.equals(Double.class)) {
            return (T) Double.valueOf(cursor.getDouble(0));
        }
        if (type.equals(float.class) || type.equals(Float.class)) {
            return (T) Float.valueOf(cursor.getFloat(0));
        }
        if (type.equals(int.class) || type.equals(Integer.class)) {
            return (T) Integer.valueOf(cursor.getInt(0));
        }
        if (type.equals(long.class) || type.equals(Long.class)) {
            return (T) Long.valueOf(cursor.getLong(0));
        }
        if (type.equals(short.class) || type.equals(Short.class)) {
            return (T) Short.valueOf(cursor.getShort(0));
        }
        if (type.equals(String.class)) {
            return (T) cursor.getString(0);
        }

        return null;
    }

    @Override
    public  Observable> observable() {
        return Observable.create(new ListOnSubscribe());
    }

    @Override
    public  Observable observableSingle() {
        return Observable.create(new ModelOnSubscribe());
    }

    @Override
    public  Observable observableValue(final Class type) {
        return Observable.create(new ValueOnSubscribe<>(type));
    }

    /**
     * Iterate over a cursor and load entities. Closes the cursor when finished.
     *
     * @param     The Model type
     * @param ellie  The {@link Ellie} instance to use.
     * @param cls    The model class.
     * @param cursor The result cursor.
     *
     * @return The list of entities.
     */
    private static  List processAndCloseCursor(final Ellie ellie, final Class cls, final Cursor cursor) {
        List entities = processCursor(ellie, cls, cursor);
        cursor.close();
        return entities;
    }

    /**
     * Iterate over a cursor and load entities.
     *
     * @param     The Model type
     * @param ellie  The {@link Ellie} instance to use.
     * @param cls    The Model class.
     * @param cursor The result cursor.
     *
     * @return The list of entities.
     */
    private static  List processCursor(final Ellie ellie, final Class cls, final Cursor cursor) {
        final List entities = new ArrayList<>();
        ModelRepository modelRepository = ellie.getModelRepository(cls);

        try {
            Constructor entityConstructor = cls.getConstructor();
            if (cursor.moveToFirst()) {
                do {
                    T entity = modelRepository.getEntity(cursor.getLong(cursor.getColumnIndex(Model.COLUMN_ID)));
                    if (entity == null) {
                        entity = entityConstructor.newInstance();
                    }

                    entity.load(cursor);
                    entities.add(entity);
                }
                while (cursor.moveToNext());
            }
        } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
            throw new IllegalStateException(e);
        }

        return entities;
    }

    private class ListOnSubscribe implements OnSubscribe> {

        @Override
        public void call(final Subscriber> subscriber) {
            final List result = fetch();
            if (!subscriber.isUnsubscribed()) {
                subscriber.onNext(result);
                subscriber.onCompleted();
            }
        }
    }

    private class ValueOnSubscribe implements OnSubscribe {

        private final Class mType;

        private ValueOnSubscribe(final Class type) {
            mType = type;
        }

        @Override
        public void call(final Subscriber subscriber) {
            final T result = fetchValue(mType);
            if (!subscriber.isUnsubscribed()) {
                subscriber.onNext(result);
                subscriber.onCompleted();
            }
        }
    }

    private class ModelOnSubscribe implements OnSubscribe {

        @Override
        public void call(final Subscriber subscriber) {
            final T result = fetchSingle();
            if (!subscriber.isUnsubscribed()) {
                subscriber.onNext(result);
                subscriber.onCompleted();
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy