Source code

Tip №1: Avoid using generating data model from packages
  1. Click to view static registry initialization via annotations example:
     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        // You can just define set of domain models and extended crud controllers (mappers) would
    11        // be added only if those models are annotated with KITTY_EXTENDED_CRUD annotation.
    12        // For example, for ComplexRandom.class it would be 
    13        // @KITTY_EXTENDED_CRUD(extendedCrudController = ComplexRandomMapper.class)
    14        domainModels = {
    15                ComplexRandomModel.class,
    16                IndexesAndConstraintsModel.class,
    17                RandomModel.class
    18        },
    19        // Or you can provide explicit assignment of model->mapper pairs by defining domainPais
    20        domainPairs = {
    21                @KITTY_REGISTRY_PAIR(model = ComplexRandomModel.class, mapper = ComplexRandomMapper.class),
    22                @KITTY_REGISTRY_PAIR(model = IndexesAndConstraintsModel.class),
    23                @KITTY_REGISTRY_PAIR(model = RandomModel.class, mapper = RandomMapper.class)
    24        }
    25)
    26public class BasicDatabase extends KittyDatabase {
    27    ...
    28}
    29  
  2. Click to view static registry initialization via overloading getStaticRegistry() method example:
     1@KITTY_DATABASE(
     2        databaseName = "basic_database",
     3        logTag = LOG_TAG,
     4        isLoggingOn = true,
     5        isProductionOn = true,
     6        isPragmaOn = true
     7)
     8public class BasicDatabase extends KittyDatabase {
     9
    10    public static final Map<Class<? extends KittyModel>, Class<? extends KittyMapper>> staticRegistry = new HashMap<>();
    11
    12    static {
    13        staticRegistry.put(ComplexRandomModel.class, ComplexRandomMapper.class);
    14        staticRegistry.put(IndexesAndConstraintsModel.class, KittyMapper.class);
    15        staticRegistry.put(RandomModel.class, RandomMapper.class);
    16    }
    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    @Override
    32    protected Map<Class, Class<KittyMapper>> getStaticRegistry() {
    33        return (Map) staticRegistry;
    34    }
    35}
    36  
Tip №2: Avoid multiply initialization of KittyDatabase
  1. Click to view KittyDatabase implementation static initialization at Application implementation example:
     1public class AwesomeApplication extends Application {
     2
     3	private static AwesomeKittyDatabaseImplementation database;
     4
     5	public void onCreate() {
     6		super.onCreate();
     7		AwesomeApplication.database = new AwesomeKittyDatabaseImplementation(getApplicationContext());
     8	}
     9
    10	public static AwesomeKittyDatabaseImplementation getAwesomeDB() {
    11		return database;
    12	}
    13}
    14  
Tip №3: Optimize your data model and statements
  1. Click to view INDEX declaration with KittyORM example:
     1@KITTY_TABLE(tableName = "cai")
     2@INDEX(indexColumns = {"creation_date"}) // Index declaration example №1
     3public class IndexesAndConstraintsModel extends KittyModel {
     4
     5
     6    ...
     7
     8    @KITTY_COLUMN(columnOrder = 5)
     9    @DEFAULT(
    10            predefinedLiteralValue = LiteralValues.CURRENT_TIMESTAMP
    11    )
    12    // Index declaration example №2
    13    @ONE_COLUMN_INDEX(unique = true, indexName = "IAC_unique_index_creation_timestamp")
    14    @NOT_NULL
    15    public Timestamp creationTmstmp;
    16
    17    ...
    18}
    19  
  2. Click to view bulk insert operation in transaction mode with KittyORM example:
     1void insertIntoDB() {
     2    // Getting mapper instance and filling model collection with random models
     3    RNDRandomModelFactory rndFactory = new RNDRandomModelFactory(Lesson2Tab5Random.this.getContext());
     4    RandomMapper mapper = (RandomMapper) getDatabase().getMapper(RandomModel.class);
     5    List<RandomModel> toInsert = new ArrayList<>();
     6    for(int i = 0; i < 50000; i++)
     7        toInsert.add(rndFactory.newRandomModel());
     8            
     9     // Saving list of 50k models in transaction mode
    10     mapper.insertInTransaction(toInsert);
    11           
    12     // Closing mapper
    13     mapper.close();
    14}
    15  
Tip №6: Turn off logging at production
  1. Click to view logging settings example:
     1@KITTY_DATABASE(
     2        isLoggingOn = false, // By default false, bootstrap and error logging
     3        isProductionOn = true, // By default true, when false - query logging
     4        isKittyDexUtilLoggingEnabled = false, // By default false, when true - a lot of logging about classes in app namespace at initialization
     5        databaseName = "mig",
     6        domainPackageNames = {"net.akaish.kittyormdemo.sqlite.migrations.migv4"},
     7        databaseVersion = 4,
     8        logTag = MigrationDBv4.LTAG
     9)
    10public class MigrationDBv4 extends KittyDatabase {
    11    ...
    12}
    13  
Tip №7: Run expensive operations not in UI thread
  1. Click to view example of KittyORM in AsyncTask:
      1    static final int INSERT_AMOUNT = 25;
      2
      3    static final String ERR_INSERT_RND = "Lesson5tab1InsertRNDDataError, see exception details!";
      4
      5    class InsertRandomAsync extends AsyncTask<Long, Long, InsertRandomResults> {
      6        ProgressDialog dialog;
      7
      8        @Override
      9        protected void onPreExecute() {
     10            dialog = ProgressDialog.show(
     11                    getLessonActivity(),
     12                    getString(R.string._l5_t1_running_requested_operation_pg_title),
     13                    getString(R.string._l5_t1_running_requested_operation_pg_body)
     14            );
     15            dialog.setCancelable(false);
     16        }
     17
     18        @Override
     19        protected InsertRandomResults doInBackground(Long... strings) {
     20            if(getSf().currentMigDBVersion() > DB_IMPLEMENTATION_VERSION) {
     21                return new InsertRandomResults(
     22                        null,
     23                        -1l,
     24                        -1l,
     25                        -1l,
     26                        false,
     27                        getSf().currentMigDBVersion()
     28                );
     29            } else {
     30                try {
     31                    KittyMapper mapper = getDatabase().getMapper(MigOneModel.class);
     32                    long recordsCount = mapper.countAll();
     33                    long affected = mapper.deleteAll();
     34                    LinkedList<MigOneModel> modelsToInsert = new LinkedList<>();
     35                    getSf().setDatabaseCreated(true);
     36                    getSf().setCurrentMigDBVersion(DB_IMPLEMENTATION_VERSION);
     37                    getSf().setDatabaseDeletedManually(false);
     38                    MigV1RandomModelFactory factory = new MigV1RandomModelFactory(getContext());
     39                    for (int i = 0; i < INSERT_AMOUNT; i++) {
     40                        MigOneModel m = factory.newM1RndModel();
     41                        modelsToInsert.addLast(m);
     42                    }
     43                    mapper.insertInTransaction(modelsToInsert);
     44                    List<MigOneModel> models = mapper.findAll();
     45                    long recordsCountAfter = mapper.countAll();
     46                    mapper.close();
     47                    Iterator<MigOneModel> mI = models.iterator();
     48                    LinkedList<String> out = new LinkedList<>();
     49                    while (mI.hasNext()) {
     50                        out.addLast(mI.next().toString());
     51                    }
     52                    return new InsertRandomResults(out, affected, recordsCount, recordsCountAfter, true, getSf().currentMigDBVersion());
     53                } catch (Exception e) {
     54                    Log.e(MigrationDBv1.LTAG, ERR_INSERT_RND, e);
     55                    if (e instanceof KittyRuntimeException) {
     56                        if (((KittyRuntimeException) e).getNestedException() != null) {
     57                            Log.e(MigrationDBv1.LTAG, ERR_INSERT_RND, ((KittyRuntimeException) e).getNestedException());
     58                        }
     59                    }
     60                    return new InsertRandomResults(
     61                            null,
     62                            -1l,
     63                            -1l,
     64                            -1l,
     65                            false,
     66                            getSf().currentMigDBVersion()
     67                    );
     68                }
     69            }
     70        }
     71
     72        @Override
     73        protected void onPostExecute(InsertRandomResults result) {
     74            dialog.cancel();
     75            if (eventsListView != null) {
     76                eventsListView.setAdapter(new BasicArrayAdapter(getContext(), new LinkedList<String>()));
     77                eventsListView.setOnTouchListener(new View.OnTouchListener() {
     78
     79                    // Setting on Touch Listener for handling the touch inside ScrollView
     80                    @Override
     81                    public boolean onTouch(View v, MotionEvent event) {
     82                        // Disallow the touch request for parent scroll on touch of child view
     83                        v.getParent().requestDisallowInterceptTouchEvent(true);
     84                        return false;
     85                    }
     86                });
     87                if (result.operationSuccess) {
     88                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_count_to_events), result.modelsCountBefore));
     89                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_deleted_to_events), result.deletedModelsAffectedRows));
     90                    for (String modelString : result.modelInsertions) {
     91                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_inserted_to_events), M1M1TN, modelString));
     92                    }
     93                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_count_to_events), result.modelsCountAfter));
     94                } else {
     95                    if(getSf().currentMigDBVersion() > DB_IMPLEMENTATION_VERSION) {
     96                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_op_mig_version_is_higher), result.dbVersion, DB_IMPLEMENTATION_VERSION));
     97                    } else {
     98                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(getString(R.string._l5_t1_error_event));
     99                    }
    100                }
    101                ((BasicArrayAdapter) eventsListView.getAdapter()).notifyDataSetChanged();
    102                reloadTableExpandedList();
    103                reloadStatus();
    104            }
    105        }
    106
    107
    108    }
    109
    110    class InsertRandomResults {
    111        List<String> modelInsertions;
    112        long deletedModelsAffectedRows;
    113        long modelsCountBefore;
    114        long modelsCountAfter;
    115        boolean operationSuccess;
    116        int dbVersion;
    117
    118        public InsertRandomResults(List<String> modelInsertions, long deletedModelsAffectedRows,
    119                                   long modelsCountBefore, long modelsCountAfter, boolean opSuccess,
    120                                   int dbVersion) {
    121            this.modelInsertions = modelInsertions;
    122            this.deletedModelsAffectedRows = deletedModelsAffectedRows;
    123            this.modelsCountBefore = modelsCountBefore;
    124            this.modelsCountAfter = modelsCountAfter;
    125            this.operationSuccess = opSuccess;
    126            this.dbVersion = dbVersion;
    127        }
    128    }
    129