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

com.abubusoft.kripton.android.annotation.BindDataSource Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright 2015, 2017 Francesco Benincasa ([email protected]).
 *
 * 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.abubusoft.kripton.android.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 

* This annotation decorate an interface to define a datasource associated to a * database schema. Between its attributes there is a DAO collection. Every DAO * is defined by an interface annotated with @{@link BindDao}. Every DAO and is * associated to a specific Java class which is associated to a specific table. * * A data source class name have to finish with DataSource suffix. *

* *

Attributes

*

* List of attributes is: *

*
    *
  • asyncTask: if true, generate async task name * `Bind<data source name without DataSource prefix>AsyncTask`
  • *
  • cursorWrapper: if true, generate a wrapped cursor for * every Java class managed by data-source. Cursor's name is * Bind{data source * name without DataSource prefix}Cursor.
  • *
  • daoSet: the collection of DAO associated to * data-source.
  • *
  • fileName: filename used to store database
  • *
  • rx: enable reactive programming support. It's necessary * to include in project RX dependencies.
  • *
  • log: controls generation of the log of SQL on * logcat.
  • *
  • typeAdapters: Global sql-type-adapters. These adapters * are applied to every property that adapter supports. See * this * page for more information.
  • *
  • version: database version. The default version is * 1.
  • *
  • schema: if true generates schema DDL in a separate file * in filder schemas. Visit * Kripton * wiki for more information about it.
  • *
* *

Usage

Consider this interface to define a data source: * *
 * @BindDataSource(daoSet = { PersonDao.class }, fileName = "feature01.db")
 * public interface SampleDataSource {
 * }
 * 
* *

* With this interface, it is defined a data source name `SampleDataSource ` and * is referred a DAO named `PersonDao`. *

* *

* When Kripton annotation processor process interface `SampleDataSource `, it * generate a class name `BindSampleDataSource ` similar to: *

* *
 * public class BindSampleDataSource extends AbstractDataSource implements BindSampleDaoFactory, SampleDataSource {
 * 	static BindSampleDataSource instance;
 * 
 * 	protected PersonDaoImpl personDao = new PersonDaoImpl(this);
 * 
 * 	private final DataSourceSingleThread _daoFactorySingleThread = new DataSourceSingleThread();
 * 
 * 	protected BindSampleDataSource(DataSourceOptions options) {
 * 		super("feature01.db", 1, options);
 * 	}
 * 
 * 	@Override
 * 	public PersonDaoImpl getPersonDao() {
 * 		return personDao;
 * 	}
 * 
 * 	public void execute(Transaction transaction) {
 * 		execute(transaction, onErrorListener);
 * 	}
 * 
 * 	public void execute(Transaction transaction, AbstractDataSource.OnErrorListener onErrorListener) {
 * 		boolean needToOpened = !this.isOpenInWriteMode();
 * 		@SuppressWarnings("resource")
 * 		SQLiteDatabase connection = needToOpened ? openWritableDatabase() : database();
 * 		try {
 * 			connection.beginTransaction();
 * 			if (transaction != null
 * 					&& TransactionResult.COMMIT == transaction.onExecute(_daoFactorySingleThread.bindToThread())) {
 * 				connection.setTransactionSuccessful();
 * 			}
 * 		} catch (Throwable e) {
 * 			Logger.error(e.getMessage());
 * 			e.printStackTrace();
 * 			if (onErrorListener != null)
 * 				onErrorListener.onError(e);
 * 		} finally {
 * 			try {
 * 				connection.endTransaction();
 * 			} catch (Throwable e) {
 * 				Logger.warn("error closing transaction %s", e.getMessage());
 * 			}
 * 			if (needToOpened) {
 * 				close();
 * 			}
 * 		}
 * 	}
 * 
 * 	public <T> T executeBatch(Batch<T> commands) {
 * 		return executeBatch(commands, false);
 * 	}
 * 
 * 	public <T> T executeBatch(Batch<T> commands, boolean writeMode) {
 * 		boolean needToOpened = writeMode ? !this.isOpenInWriteMode() : !this.isOpen();
 * 		if (needToOpened) {
 * 			if (writeMode) {
 * 				openWritableDatabase();
 * 			} else {
 * 				openReadOnlyDatabase();
 * 			}
 * 		}
 * 		try {
 * 			if (commands != null) {
 * 				return commands.onExecute(new DataSourceSingleThread());
 * 			}
 * 		} catch (Throwable e) {
 * 			Logger.error(e.getMessage());
 * 			e.printStackTrace();
 * 			throw (e);
 * 		} finally {
 * 			if (needToOpened) {
 * 				close();
 * 			}
 * 		}
 * 		return null;
 * 	}
 * 
 * 	public static synchronized BindSampleDataSource getInstance() {
 * 		if (instance == null) {
 * 			instance = new BindSampleDataSource(null);
 * 		}
 * 		return instance;
 * 	}
 * 
 * 	public static BindSampleDataSource open() {
 * 		BindSampleDataSource instance = getInstance();
 * 		instance.openWritableDatabase();
 * 		return instance;
 * 	}
 * 
 * 	public static BindSampleDataSource openReadOnly() {
 * 		BindSampleDataSource instance = getInstance();
 * 		instance.openReadOnlyDatabase();
 * 		return instance;
 * 	}
 * 
 * 	@Override
 * 	public void onCreate(SQLiteDatabase database) {
 * 		// generate tables
 * 		// log section BEGIN
 * 		if (this.logEnabled) {
 * 			Logger.info("Create database '%s' version %s", this.name, this.getVersion());
 * 		}
 * 		// log section END
 * 		// log section BEGIN
 * 		if (this.logEnabled) {
 * 			Logger.info("DDL: %s", PersonTable.CREATE_TABLE_SQL);
 * 		}
 * 		// log section END
 * 		database.execSQL(PersonTable.CREATE_TABLE_SQL);
 * 		// if we have a populate task (previous and current are same), try to
 * 		// execute it
 * 		if (options.updateTasks != null) {
 * 			SQLiteUpdateTask task = findPopulateTaskList(database.getVersion());
 * 			if (task != null) {
 * 				// log section BEGIN
 * 				if (this.logEnabled) {
 * 					Logger.info("Begin update database from version %s to %s", task.previousVersion,
 * 							task.currentVersion);
 * 				}
 * 				// log section END
 * 				task.execute(database);
 * 				// log section BEGIN
 * 				if (this.logEnabled) {
 * 					Logger.info("End update database from version %s to %s", task.previousVersion,
 * 							task.currentVersion);
 * 				}
 * 				// log section END
 * 			}
 * 		}
 * 		if (options.databaseLifecycleHandler != null) {
 * 			options.databaseLifecycleHandler.onCreate(database);
 * 		}
 * 	}
 * 
 * 	@Override
 * 	public void onUpgrade(SQLiteDatabase database, int previousVersion, int currentVersion) {
 * 		// log section BEGIN
 * 		if (this.logEnabled) {
 * 			Logger.info("Update database '%s' from version %s to version %s", this.name, previousVersion,
 * 					currentVersion);
 * 		}
 * 		// log section END
 * 		// if we have a list of update task, try to execute them
 * 		if (options.updateTasks != null) {
 * 			List<SQLiteUpdateTask> tasks = buildTaskList(previousVersion, currentVersion);
 * 			for (SQLiteUpdateTask task : tasks) {
 * 				// log section BEGIN
 * 				if (this.logEnabled) {
 * 					Logger.info("Begin update database from version %s to %s", task.previousVersion,
 * 							task.currentVersion);
 * 				}
 * 				// log section END
 * 				task.execute(database);
 * 				// log section BEGIN
 * 				if (this.logEnabled) {
 * 					Logger.info("End update database from version %s to %s", task.previousVersion,
 * 							task.currentVersion);
 * 				}
 * 				// log section END
 * 			}
 * 		} else {
 * 			// drop all tables
 * 			SQLiteUpdateTaskHelper.dropTablesAndIndices(database);
 * 
 * 			// generate tables
 * 			// log section BEGIN
 * 			if (this.logEnabled) {
 * 				Logger.info("DDL: %s", PersonTable.CREATE_TABLE_SQL);
 * 			}
 * 			// log section END
 * 			database.execSQL(PersonTable.CREATE_TABLE_SQL);
 * 		}
 * 		if (options.databaseLifecycleHandler != null) {
 * 			options.databaseLifecycleHandler.onUpdate(database, previousVersion, currentVersion, true);
 * 		}
 * 	}
 * 
 * 	@Override
 * 	public void onConfigure(SQLiteDatabase database) {
 * 		// configure database
 * 		if (options.databaseLifecycleHandler != null) {
 * 			options.databaseLifecycleHandler.onConfigure(database);
 * 		}
 * 	}
 * 
 * 	public void clearCompiledStatements() {
 * 		PersonDaoImpl.clearCompiledStatements();
 * 	}
 * 
 * 	public static synchronized BindSampleDataSource build(DataSourceOptions options) {
 * 		if (instance == null) {
 * 			instance = new BindSampleDataSource(options);
 * 		}
 * 		instance.openWritableDatabase();
 * 		instance.close();
 * 		return instance;
 * 	}
 * 
 * 	public static synchronized BindSampleDataSource build() {
 * 		return build(DataSourceOptions.builder().build());
 * 	}
 * 
 * 	public interface Transaction extends AbstractDataSource.AbstractExecutable<BindSampleDaoFactory> {
 * 		TransactionResult onExecute(BindSampleDaoFactory daoFactory);
 * 	}
 * 
 * 	public interface Batch<T> {
 * 		T onExecute(BindSampleDaoFactory daoFactory);
 * 	}
 * 
 * 	class DataSourceSingleThread implements BindSampleDaoFactory {
 * 		private SQLContextSingleThreadImpl _context;
 * 
 * 		private PersonDaoImpl _personDao;
 * 
 * 		DataSourceSingleThread() {
 * 			_context = new SQLContextSingleThreadImpl(BindSampleDataSource.this);
 * 		}
 * 
 * 		public PersonDaoImpl getPersonDao() {
 * 			if (_personDao == null) {
 * 				_personDao = new PersonDaoImpl(_context);
 * 			}
 * 			return _personDao;
 * 		}
 * 
 * 		public DataSourceSingleThread bindToThread() {
 * 			_context.bindToThread();
 * 			return this;
 * 		}
 * 	}
 * }
 * 
* *

* Generated data source class derived from AbstractDataSource.java * that derives from SQLiteOpenHelper.java. *

* *

* To use a data source in a client application, just retrieve a reference to * singleton instance of data source *

* *
 * BindSampleDataSource dataSource = BindSampleDataSource.getInstance();
 * 
*

* To execute a transaction, just invoke the following code *

* *
dataSource.execute(new Transaction() {

  @Override
  public TransationResultonExecute(BindSampleDaoFactory daoFactory) {
    DaoPersonImpl dao = daoFactory.getPersonDao();

    long result = dao.insertRaw1("test", 52);
    dao.insertRaw2("test2", 23)
    
    // commit transaction
    return TransationResult.COMMIT;
  }

});
 * 
* *

* If you want to use directly DAO without a transaction just retrieve DAO * implementation from data-source *

* *
 * PersonDaoImpl dao = dataSource.getPersonDao();
 * dao.insertRaw1("test", 52);
 * 
* * @author Francesco Benincasa ([email protected]) * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface BindDataSource { /** * DAOs to include in the database schema. * * @return class to include in the database schema */ Class[] daoSet(); /** * Name of database file. * * @return database name */ String fileName(); /** * Database version. * * @return database version */ int version() default 1; /** * if true, generate log info. * * @return true if you want to produce log code */ boolean log() default true; /** *

* if true, generate schema sql file, in schema/ folder. Visit * this page for * more information. *

* *

* The name of file will be: *

* *
	 * {name of datasource}.schema.{version}.sql
	 * 
* * Example: * *
	 * xeno.schema.1.sql
	 * 
* * @return true, if successful */ boolean schema() default false; /** * if true, generate async task. * * @return true if you want to generate async task class */ boolean asyncTask() default false; /** * if true, generate cursor wrapper. * * @return true if you want to generate cursor wrapper */ boolean cursorWrapper() default false; /** * if true, generate rx support. * * @return true if you want to generate rx support */ boolean rx() default false; /** *

* Global sql type adapters. These adapter are applied to every property * that adapter supports. This adapters are not applied to parameter of raw * methods (ones that not use a bean as parameter). *

* *

* This adapters is ovverride by specific type adapter. *

* * @return the bind sql adapter[] */ BindSqlAdapter[] typeAdapters() default {}; }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy