-
Notifications
You must be signed in to change notification settings - Fork 1
Home
#Corona SDK LORM
On Progress ...
- Query Scopes
- Global Scopes
- Eager Loading
The Lua ORM aka LORM (open for suggestions) provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table is and independent .lua file which allow you to easy control your database.
The project structure is an Corona SDK project which has been tested under Yosemite with Corona SDK build 2014.2511 so feel free to download it and test it.
##Basic Usage Let use the repo content to explain how LORM works. So lets focus on these two folders:
- DataModel
- LORM
LORMPath = "LORM"
###Defining a DataContext
The DataContext will contain the definition for our database and would also be the name of our SQLite database. What the DataContext contains is the definition for the tables, the ORM would look for .lua Model that we define in the DataContext.
--File DataModel/EMMAContext
LORMContext = {
Namespace = 'DataModel',
Database = 'EMMAContext',
Grade ={},
Classroom ={},
Teacher ={},
Student ={},
Unit ={}
}
return require(LORMPath..".lorm"):new(LORMContext)
To include the file you must only:
--
-- You can include the File AnyWhere in your project,
-- I rather to doit in the manilla
--
requiere "DataModel.EMMAContext"
###Defining A LORM Model When defining a table we can make use of the namespace variable (folder location) to define multiple tables for diferent contexts the default behaivor it let this tables accesible globally so be careful if you define multiple tables with the same name.
--
-- File DataModel/Grade.lua
--
Grade ={
Name={UNIC=true},
Units={FK={FK.hasMany,DataModel.Unit}},
Classrooms={FK={FK.hasMany,DataModel.Classroom}}
}
#####Column Attributes
DataType: [ PRIMARY | INTEGER | TEXT | VIRTUAL | COLLECTION | DATETIME ]
Unic: [ true | false]
FK[array]:
- [belongsTo | hasOne | hasMany ]
- Table from your Context
*If Primary key is not defined by default would be used Id. * All Columns are created as TEXT except FK, LORM chooses VIRTUAL or COLLECTION for Foreign Keys and the field stored in database is always and INTEGER
After the context is required you would have access to some new clases in our example we could access our Grade model by either Grade or EMMAContext.Grade if you're using only one context you're complete free to use the first but if you have multiple contexts, the second one is the right choice.
--
-- Obtiene todos los registros
--
local grades = EMMAContext.Grade:findAll()
--
-- Obtiene un sólo registro por su clave Id
--
local grade = EMMAContext.Grade:find(1)
###Querying LORM Models
local grades = EMMAContext.Grade:where('Name','LIKE','a%')->take(10)->get();
To create a new record in the database from a model, simply create a new model instance and call the save method.
local grade = EMMAContext.Grade{Name='Grade 1'}
grade:save()
Note: Because of the feather of Remote DB Sync LORM has got, when you save a new entity three fields would be created Created, Updated, Sync. The Sync field generates a device-based key so you can always have a field to sync across multi-devices.
###Updating A Retrieved Record
To update a record, you may retrieve it, change an attribute, and use the save method:
local grade = EMMAContext.Grade:find(1)
grade.Name = "Grade Updated"
grade:save()
###Saving A Record And Relationships
Sometimes you may wish to save not only a model, but also all of its relationships. To do so... well It took me a time but if you save a parent It will also save the childs who need it. Sounds cool, even better if you save a child it will first save the parent.
--
-- This example is not part of the actual repo code
--
local grade1 = Grade{Name="Grade 1"}
local grade2 = Grade{Name="Grade 2"}
local group1 = EMMAContext.Grade{Name="Group 2"}
local group2 = Grade{Name="Grop 2"}
grade1.grupos:Add(group1)
grade2.grupos:Add(group2)
--
-- Saving grade1 makes group1 be saved
--
grade1:save()
--
-- Saving group1 makes grade1 be saved
--
group1:save()
###Deleting An Existing Record
To delete a model, simply call the delete method on the instance:
local grade = EMMAContext.Grade:find(1)
grade:delete()
By default, LORM will maintain the created and updated columns on your database table automatically. This behavior is controlled by the variable:
LORMConfig.TimeStamps = [true|false]
###Timestamp Format
The current timestamp format is:
yyyy-mm-dd hh:mm:ss 2014-04-05 17:40:59
The time is store in UTF time. (I'm working on creating and special object to manage dates).
If you wish to customize the format of your timestamps, you may override the getDateFormat method in your model:
class User extends Eloquent {
protected function getDateFormat()
{
return 'U';
}
Of course, your database tables are probably related to one another. For example, a blog post may have many comments, or an order could be related to the user who placed it. LORM by the moment only support the next command relationships:
- belongsTo
- hasOne
- hasMany
###belongsTo In conjunction with hasOne this allows you to have a One To One relationship. By using belongsTo you are telling the child record to known its parent, but this command itself doesn't allows the parent to know its children.
First let's look at the Teacher.lua file:
Teacher={
Name = {UNIC=true},
Password={},
Classroom = {FK={FK.belongsTo,DataModel.Classroom}}
}
Example:
local teacher = EMMAContext.Teacher:find(1)
teacher.Classroom.Name = "Clase One"
###hasOne
By itself this command allows you to create a One to One relationship, but the children record won't its parent.
First let's look at the Classroom.lua file:
Classroom={
Name = {UNIC=true},
Teacher={FK={FK.hasOne,DataModel.Teacher}},
Students={FK={FK.hasMany,DataModel.Student}},
}
Example:
local classroom = EMMAContext.Classroom:find(1)
classroom.Teacher.Name = "John Smith"
Note: As you might suppose you can use hasOne and belongsTo together to make both, child and parent know each other for a One to One relationship.
###hasMany
By itself this property allow you to create a One to Many relationship by it won't make the children know the parent.
When you use this property the result would be a DataType.COLLECTION object which own 3 Methods Add, Remove and List.
Let's look at the Grade.lua file:
Grade={
Name={UNIC=true},
Units={FK={FK.hasMany,DataModel.Unit}},
Classrooms={FK={FK.hasMany,DataModel.Classroom}}
}
Example:
local grade = EMMAContext.Grade{Name="Grade 1"}
grade.save()
local cr1 = EMMAContext.Classroom{Name="CR1"}
local cr2 = EMMAContext.Classroom{Name="CR1"}
local cr3 = EMMAContext.Classroom{Name="CR1"}
grade.Classrooms:Add(cr1)
-- grade now contains cr1
grade.Classrooms:Add(cr2)
-- grade now contains cr1,cr2
grade.Classrooms:Remove(cr1)
-- grade now contains cr2 on index 1
grade.Classrooms:Remove(1)
-- grade now contains no classroom
grade.Classrooms:Add(cr1)
grade.Classrooms:Add(cr2)
grade.Classrooms:Add(cr3)
-- grade now contains cr1,cr2,cr3
--Access Elements as Array
print( grade.Classrooms[1] ) --Will print the cr1 variable
local classrooms = grade.Classrooms:List()[1]
--Classrooms is table arrays which only contains the three classrooms
-- I'm not sure is it'll be better to remove it...
print(classrooms[2]) --Will print the cr2 variable
Note: If you want the children to know their parent you must use the belongsTo variable on the child model. hasOne and hasMany for obvios reasons cannot be used in the same model referir to the same child, but I don't know what it would do, since I haven't test that escenario yet...