AKA - Dude, where is my primary key?
Active Record implementation for android apps
Download, install and configure the library into your project
- download all the files in the repository
- install the library by adding the downloaded files to your project as a package
- configure the library by edditing the ActiveConfig.java file:
public class ActiveConfig
{
/*
* Database Name
*
* Recommended format: "*.db"
*
*/
public static final String DATABASE_NAME = "dwimpkey.db";
/*
* Database Version
*
* should be manually incremented after any set of changes in
* the model classes decelerations that should effect the Database schema
*
* must be > 0
*
*/
public static final int VERSION = 6;
/*
* list all of your models that will behave as ActiveRecord
*
* all of them must extend ActiveRecord as well
*/
public static Class<?>[] getActiveModels()
{
return new Class[] { Product.class,
Book.class };
}
}
on the onCreate() method at the activity:
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ActiveRecord.setContext(this); // VERY IMPORTANT!
}
Here is how to generate a table named 'products' with auto incremented primary key named 'id'
public final class Product extends ActiveRecord
{
public Product() // THIS CONSTRUCTOR MUST BE IMPLEMENTED
{
super();
}
@ActiveField
public String name; // generates dataase field as slqlite TEXT
@ActiveField
public double price; // generates dataase field as slqlite REAL
@ActiveField
public int barcode; // generates dataase field as slqlite INTEGER
public String review; // no database field for this one
}
Currentlly suported types:
- int
- long
- short
- double
- float
- String
Product product = new Product(); // create new instance
product.name = "Computer";
product.barcode = 1234;
product.price = 99.99;
product.save(); // save the new instance to the database
Product product = (Product) new Product().find(1); // find row where id=1
product.price = 199.99; // update a value in the object
product.save(); // save the updated object back to the database
new Product().find(1).delete(); // find row where id=1 and delete it frome the database
Select All Rows In Table
Product[] products = new ActiveList<Product>(Product.class).toArray();
// or
ActiveList<Product> products = new ActiveList<Product>(Product.class);
generates:
SELECT * FROM products;
Chained Select
ActiveList<Product> products = new ActiveList<Product>(Product.class)
.where("price>50")
.where("price<200")
.where("name<>'Bad Product'")
.order("price ASC")
.order("name DESC")
.limit(10);
generates:
SELECT *
FROM products
WHERE price>50
AND price<200
AND name<>'Bad Product'
ORDER BY price ASC, name DESC
LIMIT 10;
One To One
Decleration:
public final class Costumer extends ActiveRecord
{
@ActiveField
public String name;
@ActiveField
public Acount bill; // holds a foreign key named bill_id
}
public final class Acount extends ActiveRecord
{
@ActiveField
public String name;
@ActiveRelation(as="bill")
public Costumer costumer; // now related to a forien key named: 'bill_id' in table 'costumers'
}
Usage:
Costumer costumer = new Costumer.find(1);
int acount_id = costumer.acount.getId(); // get the costumer's acount id with no database query
Acount acount = costumer.acount.get(); // get the costumers's acount, with a select query.
Acount acount2 = costumer.acount.get(); // no query this time, the data is allready loaded.
Acount acount3 = new Acount.find(1);
int id_1 = acount3.costumer.getId(); // this one will generate a query, because acounts doesnt hold a foreign key
int id_2 = acount3.costumer.get().getId(); // this one is better, becouse now the costumer is fully loaded
One To Many
decleration:
public final class Resturant extends ActiveRecord
{
@ActiveRelation(as="workPlace")
public ActiveList<Employee> employees;
}
public final class Employee extends ActiveRecord
{
@ActiveField
public Resturant workPlace;
}
usage:
ActiveList<Employee> employees = resturant.employees.get();
resturant.employees.add(employee); // add an employee to the list of the resturant employees
resturant.employees.saveAll(); // update the database about all the changes in that list
Many To Many
decleration:
public final class SourceCode extends ActiveRecord
{
@ActiveRelation // no need for (as="souresCodes"), as it's the default
public ActiveList<Programmer> contributers;
}
public final class Programmer extends ActiveRecord
{
@ActiveRelation(as="contributers")
public ActiveList<SourceCode> sourceCodes;
}
declaration:
public final class Page extends ActiveRecord
{
@ActiveField
public Category category;
@ActiveField
public boolean active;
@ActiveField
public int position;
public static ActiveList<Page> publicList()
{
return new ActiveList<Page>(Page.class).where("active=1").order("position ASC");
}
}
usage:
ActiveList<Page> allPublicPages = Page.publicList(); // simple use of the scope
ActiveList<Page> somePublicPages = Page.publicList().limit(10); // chain scope with other clauses
need to change implementation to make this possible:
ActiveList<Page> categoryPublicPages = category.pages.publicList(); // chain scope with relative query