/easyOrm

Xml based Android ORM

Primary LanguageJava

EasyOrm

Xml based Android ORM

This orm allows developer to create simple database using xml files.

Xml file based on 4 main tags. They are below
tables We define all tables in this section
initialize Some tables should be initialize when they are created. if you want to initialize your tables, you must use this section. This section only runs after tables are created.
queries Developers must define their all queries in this section. Every Query must have unique name.
upgradesDay after day, If we need to upgrade the our database, Main Section tag easyORM must have version attribute. When this attribute is increased, this section operations will be performed under onUpgrade method which is provided by SqLite.
Let's look at each section closer

Usage

following xml overviewl shows the general usage:

	<easyORM version="1">
		<tables>
			section1 
		</tables>
		<initialize>
			section2 
		</initialize>
		<queries>
			section3 
		</queries>
		<upgrades>
			section4 
		</upgrades>
	</easyORM>

Section 1

tables tag should include the table tags. this section allows us to define our all tables.

usage example is

	<tables>
		<table name="informations">
			<column name="ID" type="integer"/>
			<column name="address" size="250" type="varchar"/>
			<column name="phone" nullable="false" size="15" type="varchar"/>
		</table>
		<table name="users">
			<column name="ID" autoIncrement="true" primary="true" type="integer"/>
			<column name="name" size="20" type="varchar" unique="true"/>
			<column name="lastName" size="20" type="varchar"/>
			<column name="number" type="integer"/>
			<column name="infoID" reference="informations:ID" type="integer"/>
		</table>
	</tables>

Above defination creates 2 table which are informations and users.
information table has ID,address and phone columns
users table has ID,name,lastName,number and infoID columns. ID is primary key. infoID is foreign key and it refers to information table' s ID'filed.

Section 2

initialize section runs only when tables are created. If we initialize some fields/tables, it is good to use this part. There is 2 type of usage. First one is rawquery. Second one is insert
rawQuery allows us to define sql queries.
insert allows us to define sql queries using xml schema.

usage example is

	<initialize>
		<rawquery query="insert into informations(ID,address,phone) values(1,'First Address','00905343332211')"/>
		<insert into="users">
			<column name="name" value="lionell"/>
			<column name="lastName" value="messi"/>
			<column name="number" value="10"/>
			<column name="infoID" value="1"/>
		</insert>
	</initialize>

Section 3

queries this section should have query tags. query tags allow us to define select/insert/update/delete operation methods.
query must have type and name attribute. type attibute points the query type which can be select/insert/update/delete. note : getInformation getInformation2 getInformation3 and getInformation4 return the same results.

usage example is

	<query name="getInformation" columns="*" type="select">
		<table name="informations"/>
		<where name="ID"/>
	</query>
	<query name="getInformation2" type="select">
		<column name="address" />
		<column name="phone" />
		<column name="ID" />
		<table name="informations"/>
		<where name="ID"/>
	</query>
	<query name="getInformation3" columns="address" type="select">
		<column name="phone" />
		<column name="ID" />
		<table name="informations"/>
		<where name="ID"/>
	</query>
	<query name="getInformation4" columns="ID,address,phone" type="select">
		<table name="informations"/>
		<where name="ID"/>
	</query>
	<query name="getInformation3" columns="address" type="select">
		<column name="phone" />
		<table name="informations"/>
		<where name="ID"/>
	</query>
	<query name="addUser" dataSync="true" type="insert">
		<table name="users"/>
		<column name="name" type="varchar" value="?"/>
		<column name="lastName" value="?"/>
		<column name="number" type="integer" value="?"/>
		<column name="infoID" type="integer" value="?"/>
	</query>
	<query name="deleteUserByID" dataSync="true" type="delete">
		<table name="users"/>
		<where name="ID" value="?"/>
	</query>
	<query name="upduteUserByID" dataSync="true" type="update">
		<table name="users"/>
		<column name="name" value="?"/>
		<column name="lastName" value="?"/>
		<column name="number" value="?"/>
		<where name="ID" value="?"/>
	</query>

inner query defination is usable.
where tag can have select tag.
For examle :

	<query name="deleteUserByPhone" type="delete">
		<table name="users"/>
		<where name="infoID" value="?">
			<select columns="ID">
				<table name="informations"/>
				<where name="phone" value="?"/>
			</select>
		</where>
	</query>
	<query name="upduteUserByPhone" type="update">
		<table name="users"/>
		<column name="name" value="?"/>
		<column name="lastName" value="?"/>
		<where name="infoID" value="?">
			<select columns="ID">
				<table name="informations"/>
				<where name="phone" value="?"/>
			</select>
		</where>
	</query>

Section 4

upgrades section can have upgrade tags. all upgrade tags must have version attribute. Because, the upgrade tags only run its version is between db oldVersion and dbNewVersion.
Upgrade tag can have table creation or rawQuery
let's look at the usage:

	<upgrade version="2">
		<table name="locations">
			<column name="ID" type="integer"/>
			<column name="latitude" size="250" type="float"/>
			<column name="longitude" size="250" type="float"/>
			<column name="userID" reference="users:ID" type="integer"/>
		</table>
		<rawquery query="insert into locations(ID,longitude,userID) values(1,55.55,66.66,123456)"/>
	</upgrade>

Table Tag Attributes more Detail

We use the tag to create new table. table tag must have a unique name . table tag should have column defination and column name points the table filed name. So it must be unique.


Column Tag Attributes

  • name must be unique
  • type can be varchar, integer, date, boolean, float. Default values is varchar
  • primary can be true/false. It is used to define Primary Key. Default values is false
  • autoIncrement can be true/false. It is used to define Auto incr Field. Default values is false
  • unique can be true/false. It is used to define Unique Field. Default values is false
  • size should be integer value. It is used to assign size to field. Default values is 50
  • nullable can be true/false.. It is used to accept null value for the column(Field). Default values is false
  • reference can be true/false.. It is used to Define Foreign Key.Usage is tableName:itsField. Default values is false
  • Query Tag Attributes more Detail

    A query must have a unique name attribute and type attribute.
    type should be select/insert/delete/update.
    distinct is optional default is false. usage is distinct="true"
    Also it should have columns attribute. This attribute is used for select queries. if it is left empty, means that * if we select some fileds, columns should be used like select="name,lastname,number"

    query tag can have table,column,where,orderBy,groupBys,havings tags.
    query tags can have dataSync attribute. it is set to true,a data sync event is distributed to all listeners after this query is executed

    Table Tag Attributes

  • name it is mandatory attribute. it must point the valid table name. More than 1 table tags can be used.All tables will be joined
  • Columns Tag Attributes

  • name it is mandatory attribute. it must point the table field
  • sum it can be true/false. Aim is to calculate sum of filed's values. Default value is false. Valid for Select Queries
  • avg it can be true/false. Aim is to calculate avg of filed's values. Default value is false. Valid for Select Queries
  • count it can be true/false. Aim is to calculate total count of filed's values. Default value is false. Valid for Select Queries
  • alias it can be string. Aim is to assign a allias for the field. Valid for Select Queries
  • UUID it can be true/false. Aim is to generate unique number. Valid for Insert Queries
  • Where Tag Attributes

  • name it is mandatory attribute. it must point the table field
  • less it is optional attribute. if it is set to true, condition is marked as less(<). Default value is false.
  • greater it is optional attribute. if it is set to true, condition is marked as greater(>). Default value is false.
  • equals it is optional attribute. if it is set to true, condition is marked as greater(=). Default value is true.
  • process When we are using multiple where tags, where conditions will be processed as and operation. We can set process to and/or. Default value is and .
  • Examples

    if we want to define <= condition, where tag should have less="true" and equals="true".
    if we want to define < condition, where tag should have less="true" and equals="false".
    if we want to define != condition, where tag should have equals="false".

    	<where name="name" value="?" process="or" /> 
    	<where name="lastName" value="?" /> 


    Above xml code snippet output is where name=? or lastName=?
    To be continued...
    Mixed Example and its sql view

    	<query name="getUser" columns="name,surname" type="select">
    		<column name="ID" alias="SYUm" sum="true"/>
    		<column name="ID" alias="total" avg="true"/>
    		<table name="users"/>
    		<where name="ID" less="true" value="?"/>
    		<orderby name="name" describe="desc"/>
    		<orderby name="surname"/>
    		<groupbys>
    			<groupby name="name"/>
    			<groupby name="surname"/>
    			<groupby name="ID" sum="true"/>
    			<groupby name="ID" avg="true"/>
    		</groupbys>
    		<havings>
    			<having name="ID" avg="true" equals="true" less="true" process="or" value="?"/>
    			<having name="ID" equals="true" greater="true" process="or" sum="true" value="?"/>
    		</havings>
    	</query>

    Above example' s sql code is :

    	getUser
    		select  name,surname, SUM(ID)  as SYUm, AVG(ID)  as total 
    		from users  
    		Where ID <= ?   
    		GROUP BY  name , surname ,  SUM(ID)  ,  AVG(ID) 
    		HAVING  AVG(ID)  <= ?  or  SUM(ID)  >= ?
    		ORDER BY  name desc , surname asc

    Code Snippets

    We need to create a simple java class to map defined table. Class' field name must be the same with defined table column names.
    All field must have getter/setter methods. The class must have default constructor.
    Java class should be below for above table users

    	public class User {
    		private Integer ID;
    		private String name, lastName;
    		private Integer number, infoID;
    
    		public Integer getID() {
    			return ID;
    		}
    
    		public void setID(Integer ID) {
    			this.ID = ID;
    		}
    
    		public String getName() {
    			return name;
    		}
    
    		public void setName(String name) {
    			this.name = name;
    		}
    
    		public String getLastName() {
    			return lastName;
    		}
    
    		public void setLastName(String lastName) {
    			this.lastName = lastName;
    		}
    
    		public Integer getNumber() {
    			return number;
    		}
    
    		public void setNumber(Integer number) {
    			this.number = number;
    		}
    
    		public Integer getInfoID() {
    			return infoID;
    		}
    
    		public void setInfoID(Integer infoID) {
    			this.infoID = infoID;
    		}
    	}

    To create DataBase,

    	public class MainActivity extends Activity{
    		@Override
    		protected void onCreate(Bundle savedInstanceState){
    			:
    			:
    			EasyORM easyORM = EasyOrmFactory.getOrCreateDataBase(this, "dbName");
    			try {
    				EasyOrmFactory.verboseAllQueries(true);
    				EasyOrmFactory.setExactMatch(false);
    				easyORM.registerXMLSchema("db.xml");
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}

    Xml Defination is,

    	<easyORM version="1">
    	    <tables>
    		 <!--
    			  __________________________
    			 |      informations        |
    			 |__________________________|
    			 |ID | address   |  phone   | 
    			 |___|___________|__________|
    			 |___|___________|__________|
    			 |___|___________|__________|
    		 -->
    		<table name="informations">
    			<column name="ID" type="integer"/>
    			<column name="address" size="250" type="varchar"/>
    			<column name="phone" nullable="false" size="15" type="varchar"/>
    		</table>
    		 <!--
    			  ___________________________________________
    			 |                   users                   |
    			 |___________________________________________|
    			 |ID | name  |  lastName   | number | infoID |
    			 |___|_______|_____________|________|________|
    			 |___|_______|_____________|________|________|
    			 |___|_______|_____________|________|________|
    		 -->
    		<table name="users">
    			<column name="ID" autoIncrement="true" primary="true" type="integer"/>
    			<column name="name" size="20" type="varchar" unique="true"/>
    			<column name="lastName" size="20" type="varchar"/>
    			<column name="number" type="integer"/>
    			<column name="infoID" reference="informations:ID" type="integer"/>
    		</table>
    	    </tables>
    
    
    	    <!--this section runs only table is created-->
    		<initialize>
    			<rawquery query="insert into informations(ID,address,phone) values(1,'First Address','00905343332211')"/>
    			<insert into="users">
    				<column name="name" value="lionell"/>
    				<column name="lastName" value="messi"/>
    				<column name="number" value="10"/>
    				<column name="infoID" value="1"/>
    			</insert>
    		</initialize>
    		<queries>
    			<!--select operation-->
    			<query name="getInformation" type="select">
    				<table name="informations"/>
    				<where name="ID"/>
    			</query>
    				<query name="getAllUser" type="select">
    				<table name="users"/>
    			</query>
    			<query name="getUserByConstValue" distinct="true" type="select">
    				<table name="users"/>
    				<where name="lastName" value="messi"/>
    			</query>
    			<query name="getUserByLastName" distinct="true" type="select">
    				<table name="users"/>
    				<where name="lastName" value="?"/>
    			</query>
    			<query name="getUserLike" columns="*" type="select">
    				<table name="users"/>
    				<where name="lastName" like="true" type="varchar" value="%?%"/>
    			</query>
    			<query name="getUserAndInformations" columns="*" type="select">
    				<table name="users"/>
    				<table name="informations"/>
    				<where name="users.infoID" process="and" static="false" value="informations.ID"/>
    				<where name="users.ID" value="?"/>
    			</query>
    
    			<!--insert operaiton-->
    			<query name="addUser" dataSync="true" type="insert">
    				<table name="users"/>
    				<column name="name" type="varchar" value="?"/>
    				<column name="lastName" value="?"/>
    				<column name="number" type="integer" value="?"/>
    				<column name="infoID" type="integer" value="?"/>
    			</query>
    			<query name="addInformations" type="insert">
    				<table name="informations"/>
    				<column name="ID" type="integer" value="?"/>
    				<column name="address" type="double" value="?"/>
    				<column name="phone" type="double" value="?"/>
    			</query>
    
    			<!--delete operation-->
    			<query name="deleteUserByID" dataSync="true" type="delete">
    				<table name="users"/>
    				<where name="ID" value="?"/>
    			</query>
    			<query name="deleteInformationByID" dataSync="true" type="delete">
    				<table name="informations"/>
    				<where name="ID" value="?"/>
    			</query>
    			<query name="deleteUserByPhone" dataSync="true" type="delete">
    				<table name="users"/>
    				<where name="infoID" value="?">
    					<select columns="ID">
    						<table name="informations"/>
    						<where name="phone" value="?"/>
    					</select>
    				</where>
    			</query>
    
    			<!--update operations-->
    			<query name="upduteUserByID" dataSync="true" type="update">
    				<table name="users"/>
    				<column name="name" value="?"/>
    				<column name="lastName" value="?"/>
    				<column name="number" value="?"/>
    				<where name="ID" value="?"/>
    			</query>
    			<query name="upduteInformationByID" dataSync="true" type="update">
    				<table name="informations"/>
    				<column name="address" value="?"/>
    				<column name="phone" value="?"/>
    				<where name="ID" value="?"/>
    			</query>
    			<query name="upduteUserByPhone" type="update">
    				<table name="users"/>
    				<column name="name" value="?"/>
    				<column name="lastName" value="?"/>
    				<where name="infoID" value="?">
    					<select columns="ID">
    						<table name="informations"/>
    						<where name="phone" value="?"/>
    					</select>
    				</where>
    			</query>
    			<rawquery name="select1" query="select * from users where ID=?" />
    
    		</queries>
    		<upgrades>
    			<!--this ection will be executed when the version is set to 2. We have to define following table in tables tag when db version is setted to 2-->
    			<upgrade version="2">
    				<table name="locations">
    					<column name="ID" type="integer"/>
    					<column name="latitude" size="250" type="float"/>
    					<column name="longitude" size="250" type="float"/>
    					<column name="userID" reference="users:ID" type="integer"/>
    				</table>
    			</upgrade>
    		</upgrades>
    
    	</easyORM>

    To register DataSyncListener

    	EasyOrmFactory.registerDataSync(this);


    To register CreateTable and Upgrade table events

    	easyORM.registerCreateTableListener(this);


    To use insert, update , select, delete queries:

    	easyORM.getEasyExecute().insert("queryName", dbObject);

    Execution performer interface methods are

    	void delete(String queryName, Object[] params) throws QueryNotFoundException, QueryExecutionException;
    
    	void deleteObject(String queryName, Object object) throws QueryNotFoundException, QueryExecutionException, FieldNotFoundException;
    
    	boolean insert(String queryName, Object u) throws QueryNotFoundException, FieldNotFoundException, QueryExecutionException;
    
    	<T> List<T> select(String queryName, final Class<T> input) throws QueryNotFoundException, QueryExecutionException;
    
    	<T> List<T> select(String queryName, Object[] parameters, final Class<T> input) throws QueryNotFoundException, QueryExecutionException;
    
    	void delete(String queryName) throws QueryNotFoundException, QueryExecutionException;
    
    	void update(String queryName, Object[] params) throws QueryNotFoundException, QueryExecutionException;
    
    	void updateObject(String queryName, Object object) throws QueryNotFoundException, QueryExecutionException, FieldNotFoundException;
    	
    	void executeRawQuery(String queryName, Object[] params) throws QueryNotFoundException, QueryExecutionException;
    	

    log Level

    Easy ORM supports only 1 log level. To enable all logs, you should use following code. All logs will be dumped with EasyORM prefix.

    	EasyOrmFactory.verboseAllQueries(true);

    Installation

    database.xml file must be under Assets folder. To create Assets folder, File->New->Folder->Assets Folder. This selection create Assets folder next to(the same level) res folder.

    Assets Folder creation

    compile 'com.github.okayatalay:easyOrm:1.0.0' line should be added to dependencies scope.

    dependencies {
    	:
    	:
    	compile 'com.github.okayatalay:easyOrm:1.0.8'
    }
    

    maven { url 'https://jitpack.io' } should be added to into project built.gradle file under allprojects -> repositories

    allprojects {
        repositories {
    	:....
    	:....
    	maven { url 'https://jitpack.io' }
        }
    }
    

    Contact

    Feel Free to get in touch with me