Working with databases in Tizen – ActiveRecord.js library

Introduction

The aim of this article is to familiarize developers with ActiveRecord.js library and describe how to use it in Tizen applications. The library's basic operations are explained. These topics are illustrated with a sample application - game Quiz. This is the third article in the series. The previous articles covered the use of the CraftyJS library in Tizen game development (Game development with CraftyJS library - introduction and Game development with CraftyJS library - Follow up). The sample application for this article is an updated version of the one used in the previous two article - a database has been added.

ActiveRecord.js

AciveRecord.js is a small library which makes the use of databases on Tizen easy. It's part of a cross platform ActiveJS framework. ActiveRecord.js implements active record pattern. It is very similar to the Ruby implementation. Database tables and views are wrapped into classes. So every class instance is connected to a single view or row in a table. You can access the database by using these objects. It simplifies interaction with the database. To update the database you have to update the object etc. We'll explain how it works with examples. You can also see this tutorial or the documentation to find out more.

Connecting to a database

First you have to connect to the database. You can do this with the connect() function:

ActiveRecord.connect();

This method will connect with a new, empty, in-memory database. You can also load json data from a local or remote source using ActiveRecord.connect(url) or ActiceRecord.connect(json) methods, for example:

ActiveRecord.connect('my_data_source.json');

For more detailed information refer to the documentation.
When connecting to a database includes a network call you should use the "ready" event. It is triggered when ActiceRecord.js has finished loading the data.

ActiveRecord.observe('ready', function() {
    // data is loaded
});

Defining models

To create an active record class you can use the ActiveRecord.create() method.

This method takes three arguments:
- Table name (obligatory)
- Fields - fields of the newly created object. They represent table columns. The field's hash should consist of pairs: "column_name : default_value" (optional)
- Instance methods - custom methods for the table (optional)

// create questions table
var Questions = ActiveRecord.create('questions', {
    text : '',
    answer1 : '',
    answer2 : '',
    answer3 : '',
    answer4 : ''
});

The sample code above creates a "questions" table with five columns: text, answer1, answer2, answer3, answer4. It doesn't define any custom methods.You can also specify columns' type. To do this you have to set the default column value to an object containing a "type" key, with optional "length" and "value" keys.
When you use the field definition hash, as in the example above, some additional model classes are created. Let's take a look at the picture below. It shows the Model object.

Model object

Fig. 1 Model object

Some predefined functions were created, according to the field names of the model: findAllByAnswer1(), findByAnswer1() etc.

//find qustion with answer1 value "Green"
var question = Questions.findByAnswer1('Green');

// find question with id 1
var question = Questions.findById(1);

Creating records

To create records you can use the create() method of the object. You can pass values for every field separately:

var question = Question.create({
    text : "Which colour is not a name of a sea?",
    answer1 : "Green",
    answer2 : "White",
    answer3 : "Red",
    answer4 : "Black"
});

Updating records

There are several methods for changing values of existing records. The easiest way is to use the update() method:

//update question with id=1
Questions.update(1, {
    answer1 : 'White',
    answer2 : 'Green'
});

It takes two arguments:
- id - record's id,
- attributes - record's attributes with new values.

You can also pass multiple ids and an array of attributes:

//change multiple id's
Questions.update([ 1, 2 ], [{
    answer1 : 'White', // Attributes for object with id 1
    answer2 : 'Green'
}, {
    answer1 : 'Green', // Attributes for object with id 2
    answer2 : 'White'
}]);

If you have an object you want to modify you can also use the updateAttribute() or set() functions:

//update question using it's object
question.updateAttribute('answer1', 'White');

question.set('answer1', 'White');
question.save();

Destroying objects

You can destroy objects by calling the destroy() method with the object's id:

//destroy question with given id
Questions.destroy(id);

If you pass "all" as argument, all records will be deleted. You can also destroy a record using its object:

//destroy the question record
question.destroy();

The last function removes the object from the database, but doesn't destroy the object from memory.

Accessing fields

In ActiveRecord.js you can access objects' attributes via the column name.

question.answer1 //returns "Green"
question.answer1 = "White" // WRONG!

Using this method you can read the attribute's value but you can't change it. If your field name is a reserved word, or name of an ActiveRecord.js method you must use the get() function to access the property:

question.get('answer1') //returns "Green"

There is an additional function for setting field values:

//set answer1 value to "White"
question.set('answer1', 'White')

Searching through records

As mentioned in the "Defining models" section there are some predefined find functions for fields you have created. They're easy to use, although sometimes it's convenient to search with a hash of options.

// find all questions
var allQuestion = Questions.find({
all : true,
limit : 10
});

// find the first question with answer1 value equal to "White"
var question = Questions.find({
first : true,
where : {
answer1 : "White"
}
});

// find questions with complex where statement
var allQuestion = Questions.find({
where : 'answer1 = "Green" AND answer2 = "White"
});

You can use the fallowing parameters:
- Select (Array of columns),
- Where (String or Object or Array),
- Joins (String),
- Order (String),
- Limit (Number),
- Offset (Number),
- Callback (Function).

You can also execute a SQL query:

// find all questions
var questions = Questions.find('SELECT * FROM questions');

You can pass an id or an array of ids to the find() method:

var selectedQuestions = Questions.find();
var selectedQuestions = Questions.find(1,2);
var selectedQuestions = Questions.find([1,2]);

Validation

ActiveRecord.js gives you tools to validate the data inserted into your database. There are several methods available. For example, you can validate the presence of necessary fields with the validatesPresenceOf() function:

Questions.validatesPresenceOf('text');

Now you won't be able to add questions without a "text" field - the save() function will return false. The create() function always returns a record, but you can check the errors with the getErrors() function:

var question = Question.create({
    answer1 : "Green",
    answer2 : "White",
    answer3 : "Red",
    answer4 : "Black"
}); // create returns an object

var errors = question.getErrors(); // error list

You can also create more complex rules with custom error logs. To demonstrate this we'll forbid adding questions with the same "text" field value.

var Questions = ActiveRecord.create('questions', {
    text : '',
    answer1 : '',
    answer2 : '',
    answer3 : '',
    answer4 : ''
}, {
    valid : function() {
        if (Questions.findByText(this.text)) {
            this.addError('Question already in the database!');
        }
    }
});

ActiveRecord.js on Tizen

In this part of the article, we'll focus on using ActiveRecord.js on Tizen. It will be illustrated by a simple example.

Adding ActiveRecord.js to your project

To use ActiveRecord.js in you Tizen projects copy the library file to the resources and add it in the index.html file. The latest version is available here.

Now you can easily access ActiveRecord's functions from your code.

Example - quiz game

Our example is very simple. It shows the most basic functions like creating a table, writing and reading data. In the quiz game we store a list of questions in a json file. It is structured like this:

{"questions" :[
{
"text": "The continent of Africa is made up of how many countries?",
"answer1": "53",
"answer2": "22",
"answer3": "80",
"answer4": "35"
},
{
"text": "Which colour is not a name of a sea?",
"answer1": "Green",
"answer2": "White",
"answer3": "Red",
"answer4": "Black"
},

...

]
}

We also have a separate class with representation of the question object. It has two fields: text of the question and an array with answers.

var question = function(text, answers) {
    this.text = text;
    this.ans = answers;
}

We read data from file with the jQuery getJSON() function. It takes three parameters:
- url - requested URL (obligatory),
- data - plain object or string that is sent to the server with the request (optional),
- success - callback executed if the request succeeds (optional).
The success callback get's json data object. In our case it is an array of questions.

var that = this;
this.questions = new Array();

$.getJSON("questions.json", function(data) {
    for ( var i = 0; i < data.questions.length; i++) {
        var text = data.questions[i].text;
        var ans = [];
        ans[0] = data.questions[i].answer1;
        ans[1] = data.questions[i].answer2;
        ans[2] = data.questions[i].answer3;
        ans[3] = data.questions[i].answer4;
        that.questions[i] = new question(text, ans);
    }
});
Now let's take a look at the implementation with ActiveRcord.js. First, we connect to the database and define a model for question data:
// setup the database
ActiveRecord.connect();

// create questions table
this.Questions = ActiveRecord.create('questions', {
    text : '',
    answer1 : '',
    answer2 : '',
    answer3 : '',
    answer4 : ''
});

Then we fill the database with data from our json file.

// fill database with data from questions.json file
$.getJSON("questions.json", function(data) {
    for ( var i = 0; i < data.questions.length; i++) {
        that.Questions.create(data.questions[i]);
    }
});

Now our database is ready to use. We can retrieve data with the find() method. It takes the index of a question as parameter:

quiz.Questions.find(index)

To retrieve the number of items in the "questions" table use the count() function:

quiz.Questions.count()

Quiz is a very simple application and doesn't require any additional functions.

Summary

In this article, the basics of the ActiceRecord.js library have been presented. Connecting to a database, creating tables, adding, modifying and removing data was described. You could also learn how to find and validate data. These topics were illustrated by an example - Quiz game on Tizen.

첨부 파일: