Source code

KittyORM find example
 1// Initializing database instance
 2BasicDatabase db = new BasicDatabase(getContext());
 3// Getting mapper instance
 4RandomMapper mapper = (RandomMapper) db.getMapper(RandomModel.class);
 5// Getting existing model from database (assuming that 0l model exists)
 6RandomModel byIPK = mapper.findByIPK(0l);
 7// Getting existing model with rowid (assuming that 10l model exists)
 8RandomModel byRowid = mapper.findByRowID(10l);
 9// Getting all models
10List<RandomModel> all = mapper.findAll();
11// Getting model with condition (fetching 100 existing tigers)
12QueryParameters parameters = new QueryParameters();
13parameters.setOffset(0l).setLimit(100l);
14SQLiteConditionBuilder builder = new SQLiteConditionBuilder();
15builder.addField(AbstractRandomModel.RND_ANIMAL_CNAME)
16       .addSQLOperator(SQLiteOperator.EQUAL)
17       .addValue(Animals.TIGER.name());
18List<RandomModel> hundredOfTigers = mapper.findWhere(builder.build(), parameters);
19// Getting model with condition (fetching 100 existing tigers with SQLite string condition)
20hundredOfTigers = mapper.findWhere(parameters, "#?randomAnimal = ?", Animals.TIGER.name());
KittyORM count and sum examples
 1// Initializing database instance
 2BasicDatabase db = new BasicDatabase(getContext());
 3// Getting mapper instance
 4RandomMapper mapper = (RandomMapper) db.getMapper(RandomModel.class);
 5// Count all records in database
 6long count = mapper.countAll();
 7// Count all dogs
 8SQLiteConditionBuilder builder = new SQLiteConditionBuilder();
 9builder.addField(AbstractRandomModel.RND_ANIMAL_CNAME)
10       .addSQLOperator(SQLiteOperator.EQUAL)
11       .addValue(Animals.DOG.name());
12long dogsCount = mapper.countWhere(builder.build());
13// Sum all dog's random_int
14long dogsRndIntSum = mapper.sum("random_int", "#?randomAnimal = ?", Animals.DOG.name());
KittyORM extended CRUD controller registry definition example
 1// Defining at registry example
 2@KITTY_DATABASE(
 3        databaseName = "basic_database",
 4        domainPackageNames = {"net.akaish.kittyormdemo.sqlite.basicdb"},
 5        ...
 6)
 7@KITTY_DATABASE_REGISTRY(
 8        domainPairs = {
 9                @KITTY_REGISTRY_PAIR(model = ComplexRandomModel.class, mapper = ComplexRandomMapper.class),
10                @KITTY_REGISTRY_PAIR(model = IndexesAndConstraintsModel.class),
11                @KITTY_REGISTRY_PAIR(model = RandomModel.class, mapper = RandomMapper.class) // registry CRUD controller definition
12        }
13)
14public class BasicDatabase extends KittyDatabase {
15    ...
16}
17// Defining at model example
18@KITTY_TABLE
19@KITTY_EXTENDED_CRUD(extendedCrudController = RandomMapper.class) // model CRUD controller definition
20@INDEX(
21        indexName = "random_animal_index",
22        indexColumns = {AbstractRandomModel.RND_ANIMAL_CNAME}
23)
24public class RandomModel extends AbstractRandomModel {
25    ...
26}
KittyORM basic_database implementation sources
  1. Click to view BasicDatabase.class:
     1@KITTY_DATABASE(
     2        databaseName = "basic_database",
     3        domainPackageNames = {"net.akaish.kittyormdemo.sqlite.basicdb"},
     4        logTag = LOG_TAG,
     5        isLoggingOn = true,
     6        isProductionOn = true,
     7        isPragmaOn = true
     8)
     9@KITTY_DATABASE_REGISTRY(
    10        domainPairs = {
    11                @KITTY_REGISTRY_PAIR(model = ComplexRandomModel.class, mapper = ComplexRandomMapper.class),
    12                @KITTY_REGISTRY_PAIR(model = IndexesAndConstraintsModel.class),
    13                @KITTY_REGISTRY_PAIR(model = RandomModel.class, mapper = RandomMapper.class)
    14        }
    15)
    16public class BasicDatabase extends KittyDatabase {
    17
    18    public static final String LOG_TAG = "BASIC DB DEMO";
    19
    20    /**
    21     * KittyORM main database class that represents bootstrap and holder for all related with database
    22     * components.
    23     * <br> See {@link KittyDatabase#KittyDatabase(Context, String)} for more info.
    24     *
    25     * @param ctx
    26     */
    27    public BasicDatabase(Context ctx) {
    28        super(ctx);
    29    }
    30
    31}

  2. Click to view AbstractRandomModel.class:
     1public abstract class AbstractRandomModel extends KittyModel {
     2
     3    public static final String RND_INTEGER_CNAME = "rnd_int_custom_column_name";
     4    public static final String RND_ANIMAL_CNAME = "rndanimal";
     5
     6    @KITTY_COLUMN(
     7            isIPK = true,
     8            columnOrder = 0
     9    )
    10    public Long id;
    11
    12    @KITTY_COLUMN(
    13            columnOrder = 1
    14    )
    15    public int randomInt;
    16
    17    @KITTY_COLUMN(
    18            columnOrder = 2,
    19            columnName = RND_INTEGER_CNAME
    20    )
    21    public Integer randomInteger;
    22
    23    @KITTY_COLUMN(
    24            columnOrder = 3,
    25            columnName = RND_ANIMAL_CNAME
    26    )
    27    public Animals randomAnimal;
    28
    29    @KITTY_COLUMN(
    30            columnOrder = 4,
    31            columnAffinity = TypeAffinities.TEXT
    32    )
    33    public String randomAnimalName;
    34}

  3. Click to view RandomModel.class:
     1@KITTY_TABLE
     2@KITTY_EXTENDED_CRUD(extendedCrudController = RandomMapper.class)
     3@INDEX(
     4        indexName = "random_animal_index",
     5        indexColumns = {AbstractRandomModel.RND_ANIMAL_CNAME}
     6)
     7public class RandomModel extends AbstractRandomModel {
     8
     9
    10    public RandomModel() {
    11        super();
    12    }
    13
    14    @KITTY_COLUMN(columnOrder = 5)
    15    public String randomAnimalSays;
    16
    17    @Override
    18    public String toString() {
    19        return new StringBuffer(64).append("[ id = ")
    20                                            .append(id)
    21                                            .append("; randomInt = ")
    22                                            .append(Integer.toString(randomInt))
    23                                            .append("; randomInteger = ")
    24                                            .append(randomInteger)
    25                                            .append("; randomAnimal = ")
    26                                            .append(randomAnimal)
    27                                            .append("; randomAnimnalLocalizedName = ")
    28                                            .append(randomAnimalName)
    29                                            .append("; randomAnimalSays = ")
    30                                            .append(randomAnimalSays).append(" ]").toString();
    31    }
    32}

  4. Click to view RandomMapper.class:
     1package net.akaish.kittyormdemo.sqlite.basicdb;
     2
     3import net.akaish.kitty.orm.KittyMapper;
     4import net.akaish.kitty.orm.KittyModel;
     5import net.akaish.kitty.orm.configuration.conf.KittyTableConfiguration;
     6import net.akaish.kitty.orm.query.QueryParameters;
     7import net.akaish.kitty.orm.query.conditions.SQLiteCondition;
     8import net.akaish.kitty.orm.query.conditions.SQLiteConditionBuilder;
     9import net.akaish.kitty.orm.query.conditions.SQLiteOperator;
    10import net.akaish.kitty.orm.util.KittyConstants;
    11import net.akaish.kittyormdemo.sqlite.misc.Animals;
    12
    13import static net.akaish.kitty.orm.query.conditions.SQLiteOperator.AND;
    14import static net.akaish.kitty.orm.query.conditions.SQLiteOperator.LESS_OR_EQUAL;
    15import static net.akaish.kitty.orm.query.conditions.SQLiteOperator.LESS_THAN;
    16import static net.akaish.kitty.orm.query.conditions.SQLiteOperator.GREATER_OR_EQUAL;
    17import static net.akaish.kitty.orm.query.conditions.SQLiteOperator.GREATER_THAN;
    18import static net.akaish.kittyormdemo.sqlite.basicdb.AbstractRandomModel.RND_ANIMAL_CNAME;
    19
    20import java.util.List;
    21
    22
    23/**
    24 * Created by akaish on 09.08.18.
    25 * @author akaish (Denis Bogomolov)
    26 */
    27public class RandomMapper extends KittyMapper {
    28
    29    public <M extends KittyModel> RandomMapper(KittyTableConfiguration tableConfiguration,
    30                                              M blankModelInstance,
    31                                              String databasePassword) {
    32        super(tableConfiguration, blankModelInstance, databasePassword);
    33    }
    34
    35    protected SQLiteCondition getAnimalCondition(Animals animal) {
    36        return new SQLiteConditionBuilder()
    37                .addColumn(RND_ANIMAL_CNAME)
    38                .addSQLOperator("=")
    39                .addObjectValue(animal)
    40                .build();
    41    }
    42
    43    public long deleteByRandomIntegerRange(int start, int end) {
    44        return deleteWhere("#?randomInt >= ? AND #?randomInt <= ?", start, end);
    45    }
    46
    47    public long deleteByAnimal(Animals animal) {
    48        return deleteWhere(getAnimalCondition(animal));
    49    }
    50
    51    public List<RandomModel> findByAnimal(Animals animal, long offset, long limit, boolean groupingOn) {
    52        SQLiteCondition condition = getAnimalCondition(animal);
    53        QueryParameters qparam = new QueryParameters();
    54        qparam.setLimit(limit).setOffset(offset);
    55        if(groupingOn)
    56            qparam.setGroupByColumns(RND_ANIMAL_CNAME);
    57        else
    58            qparam.setGroupByColumns(KittyConstants.ROWID);
    59        return findWhere(condition, qparam);
    60    }
    61
    62    public List<RandomModel> findByIdRange(long fromId, long toId, boolean inclusive, Long offset, Long limit) {
    63        SQLiteCondition condition = new SQLiteConditionBuilder()
    64                .addColumn("id")
    65                .addSQLOperator(inclusive ? GREATER_OR_EQUAL : GREATER_THAN)
    66                .addValue(fromId)
    67                .addSQLOperator(AND)
    68                .addColumn("id")
    69                .addSQLOperator(inclusive ? LESS_OR_EQUAL : LESS_THAN)
    70                .addValue(toId)
    71                .build();
    72        QueryParameters qparam = new QueryParameters();
    73        qparam.setLimit(limit).setOffset(offset).setGroupByColumns(KittyConstants.ROWID);
    74        return findWhere(condition, qparam);
    75    }
    76
    77    public List<RandomModel> findAllRandomModels(Long offset, Long limit) {
    78        QueryParameters qparam = new QueryParameters();
    79        qparam.setLimit(limit).setOffset(offset).setGroupByColumns(KittyConstants.ROWID);
    80        return findAll(qparam);
    81    }
    82
    83}

  5. Click to view ComplexRandomModel.class:
      1@KITTY_TABLE
      2@KITTY_EXTENDED_CRUD(extendedCrudController = ComplexRandomMapper.class)
      3public class ComplexRandomModel extends AbstractRandomModel {
      4
      5    public ComplexRandomModel() {
      6        super();
      7    }
      8
      9
     10    // Primitives
     11    // (boolean, int, byte, double, long, short, float)
     12    @KITTY_COLUMN(columnOrder = 5)
     13    public boolean boolF;
     14
     15
     16    @KITTY_COLUMN(columnOrder = 6)
     17    public byte byteF;
     18
     19    @KITTY_COLUMN(columnOrder = 7)
     20    public double doubleF;
     21
     22    @KITTY_COLUMN(columnOrder = 8)
     23    public long longF;
     24
     25    @KITTY_COLUMN(columnOrder = 9)
     26    public short shortF;
     27
     28    @KITTY_COLUMN(columnOrder = 10)
     29    public float floatF;
     30
     31    // Byte array
     32    @KITTY_COLUMN(columnOrder = 11)
     33    public byte[] byteArray;
     34
     35    // String (TEXT) (String, BigDecimal, BigInteger, Enum)
     36    @KITTY_COLUMN(columnOrder = 12)
     37    public String stringF;
     38
     39    @KITTY_COLUMN(columnOrder = 13)
     40    public BigDecimal bigDecimalF;
     41
     42    @KITTY_COLUMN(columnOrder = 14)
     43    public BigInteger bigIntegerF;
     44
     45    @KITTY_COLUMN(columnOrder = 15)
     46    public Uri uriF;
     47
     48    @KITTY_COLUMN(columnOrder = 16)
     49    public File fileF;
     50
     51    @KITTY_COLUMN(columnOrder = 17)
     52    public Currency currencyF;
     53
     54    // SD
     55    @KITTY_COLUMN(
     56            columnOrder = 18,
     57            columnAffinity = TypeAffinities.TEXT
     58    )
     59    @KITTY_COLUMN_SERIALIZATION
     60    public AnimalSounds stringSDF;
     61
     62    @KITTY_COLUMN(columnOrder = 19)
     63    public SomeColours bitmapColour;
     64
     65    @KITTY_COLUMN(
     66            columnOrder = 20,
     67            columnAffinity = TypeAffinities.BLOB
     68    )
     69    @KITTY_COLUMN_SERIALIZATION
     70    public Bitmap byteArraySDF;
     71
     72    String stringSDFSerialize() {
     73        if(stringSDF == null) return null;
     74        return new GsonBuilder().create().toJson(stringSDF);
     75    }
     76
     77    AnimalSounds stringSDFDeserialize(String cvData) {
     78        if(cvData == null) return null;
     79        if(cvData.length() == 0) return null;
     80        return new GsonBuilder().create().fromJson(cvData, AnimalSounds.class);
     81    }
     82
     83    public byte[] byteArraySDFSerialize() {//byteArraySDFSerialize
     84        if(byteArraySDF == null) return null;
     85        ByteArrayOutputStream bmpStream = new ByteArrayOutputStream();
     86        byteArraySDF.compress(Bitmap.CompressFormat.PNG, 100, bmpStream);
     87        return bmpStream.toByteArray();
     88    }
     89
     90    public Bitmap byteArraySDFDeserialize(byte[] cursorData) {
     91        if(cursorData == null) return null;
     92        if(cursorData.length == 0) return null;
     93        return BitmapFactory.decodeByteArray(cursorData, 0, cursorData.length);
     94    }
     95
     96    // Primitive wrappers Boolean, Integer, Byte, Double, Short or Float
     97    @KITTY_COLUMN(columnOrder = 21)
     98    public Boolean boolFF;
     99
    100
    101    @KITTY_COLUMN(columnOrder = 22)
    102    public Byte byteFF;
    103
    104    @KITTY_COLUMN(columnOrder = 23)
    105    public Double doubleFF;
    106
    107    @KITTY_COLUMN(columnOrder = 24)
    108    public Short shortFF;
    109
    110    @KITTY_COLUMN(columnOrder = 25)
    111    public Float floatFF;
    112
    113
    114    // Long represented types Long, Date, Calendar, Timestamp
    115    @KITTY_COLUMN(columnOrder = 26)
    116    public Long longFF;
    117
    118    @KITTY_COLUMN(columnOrder = 27)
    119    public Date dateF;
    120
    121    @KITTY_COLUMN(columnOrder = 28)
    122    public Calendar calendarF;
    123
    124    @KITTY_COLUMN(columnOrder = 29)
    125    public Timestamp timestampF;
    126
    127    @Override
    128    public String toString() {
    129        StringBuffer out = new StringBuffer(256);
    130        out.append("Long id : "+id+"\r\n");
    131        out.append("int randomInt : "+randomInt+"\r\n");
    132        out.append("String stringF : "+stringF+"\r\n");
    133        out.append("BigInteger bigIntegerF : "+bigIntegerF+"\r\n");
    134        out.append("SomeColours bitmapColour : "+bitmapColour+"\r\n");
    135        out.append("Short shortFF : "+shortFF+"\r\n");
    136        out.append("Timestamp timestampF (HReadable) : "+timestampF+"\r\n");
    137        out.append("AnimalSounds stringSDF (HReadable) : "+stringSDFSerialize()+"\r\n");
    138        out.append("Uri uriF : " + uriF+"\r\n");
    139        out.append("Currency currencyF : " + currencyF.getSymbol()+"\r\n");
    140        out.append("... \r\n");
    141        return out.toString();
    142    }
    143
    144    public String toShortString() {
    145        StringBuffer out = new StringBuffer(256);
    146        out.append("[ Long id : "+id+"; ");
    147        out.append("int randomInt : "+randomInt+"; ");
    148        out.append("String stringF : "+stringF+"; ");
    149        out.append("BigInteger bigIntegerF : "+bigIntegerF+"; ");
    150        out.append("SomeColours bitmapColour : "+bitmapColour+"; ");
    151        out.append("Short shortFF : "+shortFF+"; ");
    152        out.append("Timestamp timestampF (HReadable) : "+timestampF+"; ... ]");
    153        return out.toString();
    154    }
    155
    156    @Deprecated
    157    public String toHTMLString() {
    158        StringBuffer out = new StringBuffer(2048);
    159        out.append("<br>Long id : "+id.toString()+"\r\n");
    160        out.append("<br><b>PRIMITIVES</b>"+"\r\n");
    161        out.append("<br>boolean boolF : "+Boolean.toString(boolF)+"\r\n");
    162        out.append("<br>int randomInt : "+Integer.toString(randomInt)+"\r\n");
    163        out.append("<br>byte byteF : "+Byte.toString(byteF)+"\r\n");
    164        out.append("<br>double doubleF : "+Double.toString(doubleF)+"\r\n");
    165        out.append("<br>long longF : "+Long.toString(longF)+"\r\n");
    166        out.append("<br>short shortF : "+Short.toString(shortF)+"\r\n");
    167        out.append("<br>float floatF : "+Float.toString(floatF)+"\r\n");
    168        out.append("<br>byte[] byteArray : "+byteArrayToString(byteArray)+"\r\n");
    169        out.append("<br><b>STRING AFFINITIES</b>"+"\r\n");
    170        out.append("<br>String randomAnimalName : "+randomAnimalName+"\r\n");
    171        out.append("<br>String stringF : "+stringF+"\r\n");
    172        out.append("<br>BigDecimal bigDecimalF : "+bigDecimalF.toEngineeringString()+"\r\n");
    173        out.append("<br>BigInteger bigIntegerF : "+bigIntegerF.toString()+"\r\n");
    174        out.append("<br>Animals randomAnimal : "+randomAnimal.toString()+"\r\n");
    175        out.append("<br><b>SERIALIZATION AND DESERIALIZATION</b>"+"\r\n");
    176        out.append("<br>AnimalSounds stringSDF : "+stringSDFSerialize()+"\r\n");
    177        out.append("<br>SomeColours bitmapColour : "+bitmapColour.toString()+"\r\n");
    178        out.append("<br><b>PRIMITIVE WRAPPERS</b>"+"\r\n");
    179        out.append("<br>Boolean boolFF : "+boolFF.toString()+"\r\n");
    180        out.append("<br>Integer randomInteger : "+randomInteger.toString()+"\r\n");
    181        out.append("<br>Byte byteFF : "+byteFF.toString()+"\r\n");
    182        out.append("<br>Double doubleFF : "+doubleFF.toString()+"\r\n");
    183        out.append("<br>Short shortFF : "+shortFF.toString()+"\r\n");
    184        out.append("<br>Float floatFF :"+floatFF.toString()+"\r\n");
    185        out.append("<br><b>LONG REPRESENTED TYPES</b>"+"\r\n");
    186        out.append("<br>Long longFF : "+longFF.toString()+"\r\n");
    187        out.append("<br>Date dateF : "+Long.toString(dateF.getTime())+"\r\n");
    188        out.append("<br>Calendar calendarF : "+Long.toString(calendarF.getTimeInMillis())+"\r\n");
    189        out.append("<br>Timestamp timestampF : "+Long.toString(timestampF.getTime())+"\r\n");
    190        out.append("<br>Date dateF (HReadable) : "+dateF.toString()+"\r\n");
    191        out.append("<br>Calendar calendarF (HReadable) : "+calendarF.getTime().toString()+"\r\n");
    192        out.append("<br>Timestamp timestampF (HReadable) : "+timestampF.toString()+"\r\n");
    193        return out.toString();
    194    }
    195
    196    public String byteArrayToString(byte[] toString) {
    197        String[] strings = new String[toString.length];
    198        for(int i = 0; i < toString.length; i++) {
    199            strings[i] = Byte.toString(toString[i]);
    200        }
    201        return KittyUtils.implodeWithCommaInBKT(strings);
    202    }
    203}

  6. Click to view IndexesAndConstraintsModel.class:
     1@KITTY_TABLE(tableName = "cai")
     2@FOREIGN_KEY_T(
     3        name = "CAI_FK",
     4        columns = {IndexesAndConstraintsModel.RANDOM_ID_CNAME},
     5        reference = @FOREIGN_KEY_REFERENCE(
     6                foreignTableName = "random",
     7                foreignTableColumns = {"id"},
     8                onUpdate = OnUpdateDeleteActions.CASCADE,
     9                onDelete = OnUpdateDeleteActions.CASCADE
    10        )
    11)
    12@INDEX(indexColumns = {"creation_date"})
    13public class IndexesAndConstraintsModel extends KittyModel {
    14    static final String RANDOM_ID_CNAME = "rnd_id";
    15
    16    @KITTY_COLUMN(columnOrder = 0)
    17    @PRIMARY_KEY
    18    @NOT_NULL
    19    public Long id;
    20
    21    @KITTY_COLUMN(columnOrder = 1)
    22    @NOT_NULL
    23    @UNIQUE
    24    public Long rndId;
    25
    26    @KITTY_COLUMN(columnOrder = 2)
    27    @CHECK(checkExpression = "animal IN (\"CAT\", \"TIGER\", \"LION\")") // only cats allowed to this party
    28    public Animals animal;
    29
    30    @KITTY_COLUMN(columnOrder = 3)
    31    @DEFAULT(signedInteger = 28) // You can choose for options for default declaration, if nothing set than 0 value would be used
    32    @NOT_NULL
    33    public Integer defaultNumber;
    34
    35    @KITTY_COLUMN(columnOrder = 4)
    36    @DEFAULT(
    37            predefinedLiteralValue = LiteralValues.CURRENT_DATE
    38    )
    39    @NOT_NULL
    40    public String creationDate;
    41
    42    @KITTY_COLUMN(columnOrder = 5)
    43    @DEFAULT(
    44            predefinedLiteralValue = LiteralValues.CURRENT_TIMESTAMP
    45    )
    46    @ONE_COLUMN_INDEX(unique = true, indexName = "IAC_unique_index_creation_timestamp")
    47    @NOT_NULL
    48    public Timestamp creationTmstmp;
    49
    50    @Override
    51    public String toString() {
    52        StringBuilder sb = new StringBuilder(64);
    53        sb.append("[ RowID = ").append(getRowID())
    54                .append(" ; id = ").append(id)
    55                .append(" ; rndId = ").append(rndId)
    56                .append(" ; animal = ").append(animal)
    57                .append(" ; defaultNumber = ").append(defaultNumber)
    58                .append(" ; creationDate = ").append(creationDate)
    59                .append(" ; creationTmstmp = ").append(creationTmstmp).append(" ]");
    60        return sb.toString();
    61    }
    62}

Fragment and utility code used in this tutorial
  1. Click to view RNDRandomModelFactory.class:
     1public class RNDRandomModelFactory {
     2
     3    private final Context context;
     4    private final Random randomizer;
     5
     6    private final SparseArray<String> randomAnimalSays = new SparseArray<>();
     7    private final SparseArray<String> randomAnimalLocalizedName = new SparseArray<>();
     8
     9    public RNDRandomModelFactory(Context context) {
    10        super();
    11        this.context = context;
    12        this.randomizer = new Random();
    13
    14        // Lol, getContext().getString() method is slow, calling for each new random model this method twice causes 55% of all execution time of generating new random model (!)
    15        // Right now getting those string causes only 14% of execution time
    16        randomAnimalSays.append(Animals.getLocalizedAnimalSaysResource(Animals.BEAR), context.getString(Animals.getLocalizedAnimalSaysResource(Animals.BEAR)));
    17        randomAnimalSays.append(Animals.getLocalizedAnimalSaysResource(Animals.CAT), context.getString(Animals.getLocalizedAnimalSaysResource(Animals.CAT)));
    18        randomAnimalSays.append(Animals.getLocalizedAnimalSaysResource(Animals.DOG), context.getString(Animals.getLocalizedAnimalSaysResource(Animals.DOG)));
    19        randomAnimalSays.append(Animals.getLocalizedAnimalSaysResource(Animals.GOAT), context.getString(Animals.getLocalizedAnimalSaysResource(Animals.GOAT)));
    20        randomAnimalSays.append(Animals.getLocalizedAnimalSaysResource(Animals.LION), context.getString(Animals.getLocalizedAnimalSaysResource(Animals.LION)));
    21        randomAnimalSays.append(Animals.getLocalizedAnimalSaysResource(Animals.SHEEP), context.getString(Animals.getLocalizedAnimalSaysResource(Animals.SHEEP)));
    22        randomAnimalSays.append(Animals.getLocalizedAnimalSaysResource(Animals.TIGER), context.getString(Animals.getLocalizedAnimalSaysResource(Animals.TIGER)));
    23        randomAnimalSays.append(Animals.getLocalizedAnimalSaysResource(Animals.WOLF), context.getString(Animals.getLocalizedAnimalSaysResource(Animals.WOLF)));
    24
    25
    26        randomAnimalLocalizedName.append(Animals.getLocalizedAnimalNameResource(Animals.BEAR), context.getString(Animals.getLocalizedAnimalNameResource(Animals.BEAR)));
    27        randomAnimalLocalizedName.append(Animals.getLocalizedAnimalNameResource(Animals.CAT), context.getString(Animals.getLocalizedAnimalNameResource(Animals.CAT)));
    28        randomAnimalLocalizedName.append(Animals.getLocalizedAnimalNameResource(Animals.DOG), context.getString(Animals.getLocalizedAnimalNameResource(Animals.DOG)));
    29        randomAnimalLocalizedName.append(Animals.getLocalizedAnimalNameResource(Animals.GOAT), context.getString(Animals.getLocalizedAnimalNameResource(Animals.GOAT)));
    30        randomAnimalLocalizedName.append(Animals.getLocalizedAnimalNameResource(Animals.LION), context.getString(Animals.getLocalizedAnimalNameResource(Animals.LION)));
    31        randomAnimalLocalizedName.append(Animals.getLocalizedAnimalNameResource(Animals.SHEEP), context.getString(Animals.getLocalizedAnimalNameResource(Animals.SHEEP)));
    32        randomAnimalLocalizedName.append(Animals.getLocalizedAnimalNameResource(Animals.TIGER), context.getString(Animals.getLocalizedAnimalNameResource(Animals.TIGER)));
    33        randomAnimalLocalizedName.append(Animals.getLocalizedAnimalNameResource(Animals.WOLF), context.getString(Animals.getLocalizedAnimalNameResource(Animals.WOLF)));
    34
    35    }
    36
    37    public RandomModel newRandomModel() {
    38        RandomModel out = new RandomModel();
    39        out.randomInt = randomizer.nextInt();
    40        out.randomInteger = randomizer.nextInt();
    41        out.randomAnimal = Animals.rndAnimal(randomizer);
    42        out.randomAnimalSays = randomAnimalSays.get(Animals.getLocalizedAnimalSaysResource(out.randomAnimal));
    43        out.randomAnimalName = randomAnimalLocalizedName.get(Animals.getLocalizedAnimalNameResource(out.randomAnimal));
    44        return out;
    45    }
    46}

  2. Click to view Lesson2Tab4Find.class:
      1package net.akaish.kittyormdemo.lessons.two;
      2
      3import android.app.ProgressDialog;
      4import android.os.AsyncTask;
      5import android.os.Bundle;
      6import android.view.LayoutInflater;
      7import android.view.MotionEvent;
      8import android.view.View;
      9import android.view.ViewGroup;
     10import android.widget.AdapterView;
     11import android.widget.Button;
     12import android.widget.EditText;
     13import android.widget.ListView;
     14import android.widget.TextView;
     15import android.widget.Toast;
     16
     17import net.akaish.kitty.orm.enums.AscDesc;
     18import net.akaish.kitty.orm.query.QueryParameters;
     19import net.akaish.kitty.orm.query.conditions.SQLiteCondition;
     20import net.akaish.kitty.orm.query.conditions.SQLiteConditionBuilder;
     21import net.akaish.kitty.orm.query.conditions.SQLiteOperator;
     22import net.akaish.kittyormdemo.KittyTutorialActivity;
     23import net.akaish.kittyormdemo.R;
     24import net.akaish.kittyormdemo.lessons.LessonsUriConstants;
     25import net.akaish.kittyormdemo.lessons.adapters.BasicRandomModelAdapter;
     26import net.akaish.kittyormdemo.sqlite.basicdb.AbstractRandomModel;
     27import net.akaish.kittyormdemo.sqlite.basicdb.RandomMapper;
     28import net.akaish.kittyormdemo.sqlite.basicdb.RandomModel;
     29import net.akaish.kittyormdemo.sqlite.misc.Animals;
     30
     31import java.util.ArrayList;
     32import java.util.LinkedList;
     33import java.util.List;
     34
     35import static java.text.MessageFormat.format;
     36
     37/**
     38 * Created by akaish on 03.08.18.
     39 * @author akaish (Denis Bogomolov)
     40 */
     41public class Lesson2Tab4Find extends Lesson2BaseFragment {
     42
     43    // Pagination start
     44    Button firstPage;
     45    Button pageUp;
     46    Button pageDown;
     47    Button lastPage;
     48
     49    SQLiteCondition currentCondition;
     50    FindResultsPager pager;
     51
     52    ListView pagerEntitiesLW;
     53    TextView expandedTitleTW;
     54    TextView paginationCounterTW;
     55
     56    BasicRandomModelAdapter entitiesAdapter;
     57
     58    String expandedPanelTitlePattern;
     59    String expandedPanelPageCounterTitlePattern;
     60    // Pagination end
     61
     62    // Fragment controls
     63    EditText findByIdET;
     64    Button findByIdButton;
     65
     66    EditText findByRangeStartET;
     67    EditText findByRangeEndET;
     68    Button findByRangeButton;
     69
     70    Button findByAnimalButton;
     71
     72    Button findAllButton;
     73
     74    public Lesson2Tab4Find(){};
     75
     76    @Override
     77    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     78        View rootView = inflater.inflate(R.layout.lesson2_tab4_find, container, false);
     79
     80        setAnimalSpinner(rootView, R.id.l2_t4_spinner, new AdapterView.OnItemSelectedListener() {
     81            @Override
     82            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
     83
     84            }
     85
     86            @Override
     87            public void onNothingSelected(AdapterView<?> parent) {
     88
     89            }
     90        });
     91
     92        setUpPagination(rootView);
     93
     94        findByIdET = rootView.findViewById(R.id.l2_t4_et_id);
     95        findByIdButton = rootView.findViewById(R.id.l2_t4_find_by_id_button);
     96        findByIdButton.setOnClickListener(new View.OnClickListener() {
     97            @Override
     98            public void onClick(View v) {
     99                findById();
    100            }
    101        });
    102
    103        findByRangeStartET = rootView.findViewById(R.id.l2_t4_et_id_range_start);
    104        findByRangeEndET = rootView.findViewById(R.id.l2_t4_et_id_range_end);
    105        findByRangeButton = rootView.findViewById(R.id.l2_t4_find_by_range_button);
    106        findByRangeButton.setOnClickListener(new View.OnClickListener() {
    107            @Override
    108            public void onClick(View v) {
    109                findByRange();
    110            }
    111        });
    112
    113        findByAnimalButton = rootView.findViewById(R.id.l2_t4_find_by_animal);
    114        findByAnimalButton.setOnClickListener(new View.OnClickListener() {
    115            @Override
    116            public void onClick(View v) {
    117                findByAnimal();
    118            }
    119        });
    120
    121        findAllButton  = rootView.findViewById(R.id._l2_t4_find_all_button);
    122        findAllButton.setOnClickListener(new View.OnClickListener() {
    123            @Override
    124            public void onClick(View v) {
    125                findAll();
    126            }
    127        });
    128
    129        reloadPager();
    130
    131        return rootView;
    132    }
    133
    134    void findById() {
    135        String inputId = findByIdET.getText().toString();
    136        if(inputId == null) {
    137            getLessonActivity().showWarningDialog(
    138                    R.string._warning_dialog_title,
    139                    R.string._l2_t4_find_by_id_message,
    140                    R.string._warning_dialog_ok_button_text
    141            );
    142            return;
    143        }
    144        if(inputId.length() == 0) {
    145            getLessonActivity().showWarningDialog(
    146                    R.string._warning_dialog_title,
    147                    R.string._l2_t4_find_by_id_message,
    148                    R.string._warning_dialog_ok_button_text
    149            );
    150            return;
    151        }
    152        Long idToFind = null;
    153        try {
    154            idToFind = Long.valueOf(inputId);
    155        } catch (Exception e) {
    156            getLessonActivity().showWarningDialog(
    157                    R.string._warning_dialog_title,
    158                    R.string._l2_t4_find_by_id_message,
    159                    R.string._warning_dialog_ok_button_text
    160            );
    161            return;
    162        }
    163        if(idToFind < 1) {
    164            getLessonActivity().showWarningDialog(
    165                    R.string._warning_dialog_title,
    166                    R.string._l2_t4_find_by_id_must_be_positive,
    167                    R.string._warning_dialog_ok_button_text
    168            );
    169            return;
    170        }
    171        SQLiteConditionBuilder builder = new SQLiteConditionBuilder();
    172        builder.addColumn("id").addSQLOperator(SQLiteOperator.EQUAL).addValue(idToFind);
    173        setPaginationResults(builder.build());
    174    }
    175
    176    void findByRange() {
    177        String rangeStart = findByRangeStartET.getText().toString();
    178        String rangeEnd = findByRangeEndET.getText().toString();
    179        if(rangeStart == null || rangeEnd == null) {
    180            getLessonActivity().showWarningDialog(
    181                    R.string._warning_dialog_title,
    182                    R.string._l2_t4_find_by_range_message,
    183                    R.string._warning_dialog_ok_button_text
    184            );
    185            return;
    186        }
    187        if(rangeStart.length() == 0 || rangeEnd.length() == 0) {
    188            getLessonActivity().showWarningDialog(
    189                    R.string._warning_dialog_title,
    190                    R.string._l2_t4_find_by_range_message,
    191                    R.string._warning_dialog_ok_button_text
    192            );
    193            return;
    194        }
    195        int rangeStartInt = 0; int rangeEndInt = 0;
    196        try {
    197            rangeStartInt = Integer.parseInt(rangeStart);
    198            rangeEndInt = Integer.parseInt(rangeEnd);
    199        } catch (Exception e) {
    200            getLessonActivity().showWarningDialog(
    201                    R.string._warning_dialog_title,
    202                    R.string._l2_t4_find_by_range_message,
    203                    R.string._warning_dialog_ok_button_text
    204            );
    205            return;
    206        }
    207        SQLiteConditionBuilder builder = new SQLiteConditionBuilder();
    208        builder.addColumn("random_int")
    209                .addSQLOperator(SQLiteOperator.GREATER_OR_EQUAL)
    210                .addValue(rangeStartInt)
    211                .addSQLOperator(SQLiteOperator.AND)
    212                .addColumn("random_int")
    213                .addSQLOperator(SQLiteOperator.LESS_OR_EQUAL)
    214                .addValue(rangeEndInt);
    215        setPaginationResults(builder.build());
    216    }
    217
    218    void findByAnimal() {
    219        String animalStr = (String) animalSpinner.getSelectedItem();
    220        if(animalStr.equals(animalAdapter.getItem(animalAdapter.getCount()))) {
    221            getLessonActivity().showWarningDialog(
    222                    R.string._warning_dialog_title,
    223                    R.string._l2_t4_find_by_animal_message,
    224                    R.string._warning_dialog_ok_button_text
    225            );
    226            return;
    227        }
    228        Animals animal = Animals.valueOf(animalStr);
    229        SQLiteConditionBuilder builder = new SQLiteConditionBuilder();
    230        builder.addColumn(AbstractRandomModel.RND_ANIMAL_CNAME)
    231                .addSQLOperator(SQLiteOperator.EQUAL)
    232                .addValue(animal.name());
    233        setPaginationResults(builder.build());
    234    }
    235
    236    void findAll() {
    237        currentCondition = new SQLiteConditionBuilder().addValue(1)
    238                                                       .build();
    239        setPaginationResults(currentCondition);
    240    }
    241
    242    @Override
    243    public void onVisible() {
    244        reloadPager();
    245    }
    246
    247    void reloadPager() {
    248        new ReloadPagerTask().execute(0l);
    249    }
    250
    251    void setUpPagination(View root) {
    252        firstPage = root.findViewById(R.id._l2_t4_pagination_at_start);
    253        pageUp = root.findViewById(R.id._l2_t4_pagination_page_up);
    254        pageDown = root.findViewById(R.id._l2_t4_pagination_page_down);
    255        lastPage = root.findViewById(R.id._l2_t4_pagination_end);
    256        pagerEntitiesLW = root.findViewById(R.id._l2_t4_find_result_enteties_list);
    257        paginationCounterTW = root.findViewById(R.id._l2_t4_page_counter);
    258        expandedTitleTW = root.findViewById(R.id._l2_t4_expanded_panel_title);
    259        entitiesAdapter = new BasicRandomModelAdapter(getContext(), new LinkedList<RandomModel>());
    260        pagerEntitiesLW.setAdapter(entitiesAdapter);
    261        pagerEntitiesLW.setOnTouchListener(new View.OnTouchListener() {
    262
    263            // Setting on Touch Listener for handling the touch inside ScrollView
    264            @Override
    265            public boolean onTouch(View v, MotionEvent event) {
    266                // Disallow the touch request for parent scroll on touch of child view
    267                v.getParent().requestDisallowInterceptTouchEvent(true);
    268                return false;
    269            }
    270        });
    271        pagerEntitiesLW.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    272            @Override
    273            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    274                RandomModel model = entitiesAdapter.getItem(position);
    275                Toast.makeText(
    276                        getLessonActivity(),
    277                        format(
    278                                getString(R.string._l2_t4_pager_select_entity_pattern),
    279                                model.id
    280                        ), Toast.LENGTH_SHORT
    281                ).show();
    282                setLoadedModelId(model.id);
    283
    284            }
    285        });
    286        expandedPanelTitlePattern = getString(R.string._l2_t4_expanded_title_pattern);
    287        expandedPanelPageCounterTitlePattern = getString(R.string._l2_t4_pager_pattern);
    288        paginationCounterTW.setText(format(expandedPanelPageCounterTitlePattern,0, 0));
    289        expandedTitleTW.setText(format(expandedPanelTitlePattern, 0));
    290        firstPage.setOnClickListener(new View.OnClickListener() {
    291            @Override
    292            public void onClick(View v) {
    293                loadPage(1l);
    294            }
    295        });
    296        pageUp.setOnClickListener(new View.OnClickListener() {
    297            @Override
    298            public void onClick(View v) {
    299                if(pager != null) {
    300                    loadPage(pager.currentPage-1);
    301                }
    302            }
    303        });
    304        pageDown.setOnClickListener(new View.OnClickListener() {
    305            @Override
    306            public void onClick(View v) {
    307                if(pager != null) {
    308                    loadPage(pager.currentPage+1);
    309                }
    310            }
    311        });
    312        lastPage.setOnClickListener(new View.OnClickListener() {
    313            @Override
    314            public void onClick(View v) {
    315                if(pager != null) {
    316                    loadPage(pager.getPagesCount());
    317                }
    318            }
    319        });
    320    }
    321
    322    void setPaginationResults(SQLiteCondition condition) {
    323        RandomMapper mapper = getMapper();
    324        this.currentCondition = condition;
    325        this.pager = new FindResultsPager(mapper.countWhere(condition, null));
    326        mapper.close();
    327        loadPage(1l);
    328    }
    329
    330    void setPaginationButtonsState() {
    331        if(pager == null || currentCondition == null) {
    332            firstPage.setEnabled(false);
    333            firstPage.setTextColor(getColourForPB(false));
    334            pageUp.setEnabled(false);
    335            pageUp.setTextColor(getColourForPB(false));
    336            pageDown.setEnabled(false);
    337            pageDown.setTextColor(getColourForPB(false));
    338            lastPage.setEnabled(false);
    339            lastPage.setTextColor(getColourForPB(false));
    340        } else {
    341            firstPage.setEnabled(!pager.isFirstPage());
    342            firstPage.setTextColor(getColourForPB(!pager.isFirstPage()));
    343            pageUp.setEnabled(!pager.isFirstPage());
    344            pageUp.setTextColor(getColourForPB(!pager.isFirstPage()));
    345            pageDown.setEnabled(!pager.isLastPage());
    346            pageDown.setTextColor(getColourForPB(!pager.isLastPage()));
    347            lastPage.setEnabled(!pager.isLastPage());
    348            lastPage.setTextColor(getColourForPB(!pager.isLastPage()));
    349        }
    350    }
    351
    352    int getColourForPB(boolean isActive) {
    353        if(isActive)
    354            return getResources().getColor(R.color.colorGrayLightest);
    355        return getResources().getColor(R.color.colorPrimaryDark);
    356    }
    357
    358    void loadPage(long pageNumber) {
    359        if(currentCondition == null || pager == null) {
    360            entitiesAdapter.notifyDataSetChanged();
    361            paginationCounterTW.setText(format(expandedPanelPageCounterTitlePattern, 0, 0));
    362            expandedTitleTW.setText(format(expandedPanelTitlePattern, 0));
    363            setPaginationButtonsState();
    364            return;
    365        }
    366
    367        pager.setCurrentPage(pageNumber);
    368        entitiesAdapter.clear();
    369
    370        RandomMapper mapper = getMapper();
    371        List<RandomModel> page = mapper.findWhere(currentCondition, pager.getQueryParameter());
    372        mapper.close();
    373        if(page == null) {
    374            entitiesAdapter.notifyDataSetChanged();
    375            paginationCounterTW.setText(format(expandedPanelPageCounterTitlePattern, 0, 0));
    376            expandedTitleTW.setText(format(expandedPanelTitlePattern, 0));
    377        } else {
    378            entitiesAdapter.addAll(page);
    379            entitiesAdapter.notifyDataSetChanged();
    380            paginationCounterTW.setText(format(
    381                    expandedPanelPageCounterTitlePattern,
    382                    pager.currentPage,
    383                    pager.getPagesCount()
    384            ));
    385            expandedTitleTW.setText(format(expandedPanelTitlePattern, pager.entitiesAmount));
    386        }
    387        setPaginationButtonsState();
    388    }
    389
    390    class FindResultsPager {
    391        long entitiesAmount;
    392        long currentPage = 1l;
    393        final long entitiesPerPage = 50l;
    394
    395        void setCurrentPage(long pageNumber) {
    396            if(getPagesCount() == 0) {
    397                currentPage = 1l;
    398                return;
    399            }
    400            if(pageNumber < 1l) {
    401                currentPage = 1l;
    402                return;
    403            }
    404            if(pageNumber > getPagesCount()) {
    405                currentPage = getPagesCount();
    406                return;
    407            }
    408            currentPage = pageNumber;
    409        }
    410
    411        boolean isFirstPage() {
    412            if(currentPage == 1l) return true;
    413            return false;
    414        }
    415
    416        boolean isLastPage() {
    417            if(currentPage == getPagesCount()) return true;
    418            return false;
    419        }
    420
    421        long getPagesCount() {
    422            if((entitiesAmount % entitiesPerPage) > 0) {
    423                return (entitiesAmount / entitiesPerPage)+1;
    424            } else {
    425                return (entitiesAmount / entitiesPerPage);
    426            }
    427        }
    428
    429        FindResultsPager(long entitiesAmount) {
    430            this.entitiesAmount = entitiesAmount;
    431        }
    432
    433        long getCurrentPage() {
    434            return currentPage;
    435        }
    436
    437        long getOffset(long pageNumber) {
    438            return entitiesPerPage * pageNumber;
    439        }
    440
    441        long getLimit() {
    442            return entitiesPerPage;
    443        }
    444
    445        QueryParameters getQueryParameter() {
    446            QueryParameters parameters = new QueryParameters();
    447            parameters.setLimit(entitiesPerPage);
    448            long offset = (currentPage - 1) * entitiesPerPage;
    449            parameters.setOffset(offset);
    450            parameters.setOrderByColumns("id");
    451            parameters.setOrderAscDesc(AscDesc.ASCENDING);
    452            return parameters;
    453        }
    454    }
    455
    456
    457    // Fab menu section
    458    // Fab menu section
    459
    460    @Override
    461    public View.OnClickListener helpFabMenuAction() {
    462        return new View.OnClickListener() {
    463            @Override
    464            public void onClick(View v) {
    465                ((KittyTutorialActivity)getActivity()).showWebViewDialog(LessonsUriConstants.L2_T4_TUTORIAL);
    466            }
    467        };
    468    }
    469
    470    @Override
    471    public View.OnClickListener sourceFabMenuAction() {
    472        return new View.OnClickListener() {
    473            @Override
    474            public void onClick(View v) {
    475                ((KittyTutorialActivity)getActivity()).showWebViewDialog(LessonsUriConstants.L2_T4_SOURCE);
    476            }
    477        };
    478    }
    479
    480    @Override
    481    public View.OnClickListener schemaFabMenuAction() {
    482        return new View.OnClickListener() {
    483            @Override
    484            public void onClick(View v) {
    485                ((KittyTutorialActivity)getActivity()).showWebViewDialog(LessonsUriConstants.L2_T4_SCHEMA);
    486            }
    487        };
    488    }
    489
    490    @Override
    491    protected int snackbarMessageResource() {
    492        return R.string._l2_t4_snackbar_message;
    493    }
    494
    495    class ReloadPagerTask extends AsyncTask<Long, Long, ArrayList<RandomModel>> {
    496        ProgressDialog dialog;
    497
    498        @Override
    499        protected void onPreExecute() {
    500        }
    501
    502        @Override
    503        protected ArrayList<RandomModel> doInBackground(Long... params) {
    504            long oldPage = 1l;
    505            if(pager != null)
    506                oldPage = pager.currentPage;
    507            RandomMapper mapper = getMapper();
    508            pager = new FindResultsPager(mapper.countWhere(currentCondition, null));
    509            mapper.close();
    510            ArrayList<RandomModel> page = getPage(1l);
    511            if(pager != null) {
    512                if(oldPage != 1l) {
    513                    if(oldPage <= pager.getPagesCount()) {
    514                        page = getPage(oldPage);
    515                    }
    516                }
    517            }
    518            return page;
    519        }
    520
    521        private ArrayList<RandomModel> getPage(Long pageNumber) {
    522            if(currentCondition == null || pager == null) {
    523                return null;
    524            }
    525            pager.setCurrentPage(pageNumber);
    526            RandomMapper mapper = getMapper();
    527            ArrayList<RandomModel> page = (ArrayList)mapper.findWhere(currentCondition, pager.getQueryParameter());
    528            mapper.close();
    529            return page;
    530        }
    531
    532        @Override
    533        protected void onPostExecute(ArrayList<RandomModel> result) {
    534//            dialog.cancel();
    535            if(currentCondition == null || pager == null) {
    536                entitiesAdapter.notifyDataSetChanged();
    537                paginationCounterTW.setText(format(expandedPanelPageCounterTitlePattern, 0, 0));
    538                expandedTitleTW.setText(format(expandedPanelTitlePattern, 0));
    539                setPaginationButtonsState();
    540                return;
    541            } else {
    542                entitiesAdapter.clear();
    543                if(result == null) {
    544                    entitiesAdapter.notifyDataSetChanged();
    545                    paginationCounterTW.setText(format(expandedPanelPageCounterTitlePattern, 0, 0));
    546                    expandedTitleTW.setText(format(expandedPanelTitlePattern, 0));
    547                } else {
    548                    entitiesAdapter.addAll(result);
    549                    entitiesAdapter.notifyDataSetChanged();
    550                    paginationCounterTW.setText(format(
    551                            expandedPanelPageCounterTitlePattern,
    552                            pager.currentPage,
    553                            pager.getPagesCount()
    554                    ));
    555                    expandedTitleTW.setText(format(expandedPanelTitlePattern, pager.entitiesAmount));
    556                }
    557                setPaginationButtonsState();
    558            }
    559        }
    560    }
    561}