Using MongoDB with Rails 3 application

On August 26, 2010, in Technologies, by khanh


1. Introduction

Instruction on how to setup environment and create a simple Rails 3 application has been shown in here. In addition, an introduction to MongoDB has also been given in the previous post. And now, the purpose of this entry is to combine those two things together: using MongoDB with Rails 3 application.

Mongo Mapper

2. Setup Rails 3 application using MongoDB

First of all, we need to install the gems to use MongoDB:

$ sudo gem install mongo_mapper –source ‘http://gemcutter.org’
$ sudo gem install bson_ext

Create a new Rails 3 application (with the name “mongo”) that does not use ActiveRecord

$ rails new mongo –skip-active-record

Open to edit the Gemfile to include mongodb gem:

$ cd mongo
$ nano Gemfile

Add the following to top of the Gemfile file:

require ‘rubygems’
require ‘mongo’
source ‘http://gemcutter.org’
gem “mongo_mapper”

Create a file called “mongo.rb” and put it in config/initializers/. Here is the content of the file

MongoMapper.connection = Mongo::Connection.new(‘localhost’, 27017)
MongoMapper.database = “mongo_#{Rails.env}”
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
MongoMapper.connection.connect_to_master if forked
end
end

You can change MongoDB’s host (which is “localhost” by default) , port (which is 27017 by default) or the database name.

Create a simple model by creating file app/models/student.rb. Here is the content of the file:

class Student
include MongoMapper::Document
end

3. Test the application

To test the application, we need to start the MongoDB server

$ MONGODB_HOME/bin/mongod –dbpath <your_database_location>

Open the Rails console

$ rails console (you may need to install irb first using “sudo apt-get install irb”)

and create a Student model object:

>> Student.create(:name => “Khanh”, :age => 27, :comment => “Falcuty of Software Engineering”)

Now we use MongoDB client to connect to Mongo DB database (the database name should be “mongo_development”) and verify that a new record has been added to the Students document

$ MONGODB_HOME/bin/mongo
> use mongo_development;
> db.students.find();

4. References

http://www.mongodb.org/display/DOCS/Rails+3+-+Getting+Started

http://github.com/banker/mongodb-rails3-sample

Tagged with:  

MongoDB replication

On August 25, 2010, in Technologies, by khanh


1. Introduction

In the previous post, I have given an introduction about NoSQL as well as how to get started with MongoDB, a document store database. This entry will continue on MongoDB but be a little bit more advance about MongoDB replication. For those who are new to database replication, here is a brief explanation:

Database replication is the process of sharing data so as to ensure consistency between multiple database server instances to improve reliability, fault-tolerance or accessibility

MongoDB supports replication of data between servers for failover and redundancy. There are 3 types of replication configuration:

  • Master-Slave Replication
  • Replica Pairs (has been replaced by Replica Sets from version 1.6)
  • Replica Sets

MongoDB replication

2. Master-Slave Replication

One database server (the “master”) is in charge and multiple database servers (the “slaves”) keep copies of all the data that’s been written to the master and can optionally be queried. Slaves cannot be written to directly, they are just copies of the master database. Setting up a master and slaves allows us to scale reads nicely because we can just keep adding slaves to increase your read capacity. Slaves also make great backup machines because if our master explodes, we still have our data safe on the slave.

To configure master-slave replication, we’ll need to start at least two instances of the database, one in master mode, and the other in slave mode.

To start the master:

$ bin/mongod –master [--dbpath /data/masterdb/]

To start the slave:

$ bin/mongod –slave –source <masterhostname>[:<port>]  [--dbpath /data/slavedb/]

The following example start the master and 2 slaves on the same computer. The master runs on default port (27017) and its data are stored in /data/db/master. The 2 slaves run on port 27018 and 27019. Their data are stored in /data/db/slave1 and /data/db/slave2:

$ bin/mongod –master –dbpath /data/db/master
$ bin/mongod –slave –port 27018 –source localhost –dbpath /data/db/slave1
$ bin/mongod –slave –port 27019 –source localhost –dbpath /data/db/slave2

3. Replica Pairs (has been replaced by Replica Sets from version 1.6)

For older version of MongoDb ( < 1.6), replica pairs are used. It is like master-slave, but we get automatic failover: if the master becomes unavailable, the slave will become a master. So, it’s basically the same as master-slave, but the servers know about each other and there is, optionally, an arbiter server that doesn’t do anything other than resolve “disputes” over who is master.

To start a pair of databases in this mode, run the following command for each:

$ bin/mongod –pairwith <remoteserver> –arbiter <arbiterserver>

whereas:

  • remoteserver: is the hostname of the other server in the pair. Append :port to the server hostname if you wish to run on a non-standard port number.
  • arbiterserver: is the hostname (and optional port number) of an arbiter. An arbiter is a Mongo database server that helps negotiate which member of the pair is master at a given point in time. Arbiter is optional.

For example, we can run the arbiter on port 5000:

$ bin/mongod –port 50000 –dbpath /data/db/arbiter

then run the two servers on port 6000 and 6001:

$ bin/mongod –port 60000 –dbpath ~/dbs/replica1 –pairwith localhost:60001 –arbiter localhost:50000
$ bin/mongod –port 60001 –dbpath ~/dbs/replica2 –pairwith localhost:60000 –arbiter localhost:50000

4. Replica Sets

From version 1.6, Replica Sets has replaced the deprecated Replica Pairs. A replica set is group of N MongoDB nodes that work together to provide automated failover. Setting up a replica set is a two-steps process that requires starting each node and then formally initiating the set. The following example will create a replica set of 3 MongoDB nodes on the same machine:

First, we will start each MongoDB nodes with the –replSet parameter. The parameter requires us to specify the name of the replica set. Let’s call our replica set “khanh”:

$ bin/mongod –replSet khanh –port 27017 –dbpath /data/db/node1
$ bin/mongod –replSet khanh –port 27018 –dbpath /data/db/node2
$ bin/mongod –replSet khanh –port 27019 –dbpath /data/db/node3

Now we will need to initialize our replica set by connecting to one of the members and running the replSetInitiate command. This command takes a configuration object that specifies the name of the set and each of the members.

$ bin/mongo localhost:27017
> config = {_id: ‘khanh’, members: [{_id: 0, host: 'localhost:27017'}, {_id: 1, host: 'localhost:27018'}, {_id: 2, host: 'localhost:27019'}]}
> rs.initiate(config);

If everything is OK, we get a response saying that the replica set will be online in a minute:

{
“info” : “Config now saved locally.  Should come online in about a minute.”,
“ok” : 1
}

During this time, one of the nodes will be elected master. We can check the status of the set by the command:

> rs.status()

The value of myState in the status response tells whether the node that we are connected to is a master or a slave. The value of myState is 1 indicates that we are connected to the master node, a value of 2 indicates a slave.

5. References

http://www.mongodb.org/display/DOCS/Replication

Tagged with:  

Introduction to NoSQL with MongoDB

On August 24, 2010, in Technologies, by khanh


1. Introduction to NoSQL

By definition, NoSQL is a term used to designate databases which differ from classic relational databases  in some way. These data stores may not require fixed table schemas, and usually avoid join  operations. Here are the list of characteristics that NoSQL databases usually have:

  • Non-relational
  • Distributed
  • Horizontal scalable
  • Schema-free
  • Eventually consistent

NoSQL

NoSQL databases can be categorised according to their characteristics and structure. Here are 3 main categories of NoSQL databases:

  • Column Store: stores content by column and column family rather than by row. More information about this type of NoSQL will be given in another post later. Cassandra (used by Facebook and Twitter) is an example of this category of NoSQL
  • Key-Value Store: data is stored in key-value format. Example: Tokyo Cabinet, Keyspace …
  • Document Store: data are not stored in tables with uniform sized fields for each record. Instead, each record is stored as a document that has certain characteristics. CouchDB and MongoDB are well-known examples in this category of NoSQL

2.  Overview of MongoDB

MongoDB bridges the gap between key-value stores (which are fast and highly scalable) and traditional RDBMS systems (which provide rich queries and deep functionality). MongoDB can be categorised as Document Store NoSQL, which means that each record is stored as a document that has certain characteristics. Any number of fields of any length can be added to a document and fields can also contain multiple pieces of data. Here is an example of a document:

{name : “Khanh, age : 27, hobby : “computer, games”}

A document can be nested into another document. For example:

{name : “Mai” , age : 27,  husband : {name : “Khanh, age : 27, hobby : “computer, games”}}

Here is a brief explanation about the structure of MongoDB: At the top level, we have a database, database can contain multiple collections and each collection can have multiple documents. If you come from a SQL background (such as MySQL), the following comparison can be helpful:

  • Database (MongoDB) = Database (MySQL)
  • Collection (MongoDB) = Table (MySQL). However, a collection in MongoDB does not have a fixed schema
  • Document (MongoDB) = Row (MySQL)

mongo

3. Setup and getting started with MongoDB

First of all, we need to download MongoDB and extract it. MongoDB can be downloaded at http://www.mongodb.org/downloads

Now we will prepare the location for MongoDB to store data. By default, MongoDB will stored data in /data/db, we will create that folder and set the permission:

$ sudo mkdir -p /data/db/
$ sudo chown `id -u` /data/db

To run the MongoDB server, go to the folder where we have extracted the downloaded MongoDB (from now we call it MONGO_HOME) and type

bin/mongod

If we don’t want to use the default data location, we can specify our data location with parameter –dbpath

bin/mongod –dbpath=your_data_location

After starting the server, open another console, go to MONGO_HOME and type the following command to start the client:

bin/mongo

To list all databases, use the command:

show dbs

By default, MongoDB will use the database “test”. To use another database, use the command “use” as following:

use your_database_name

If you use a non existing database, it will be automatically created after inserting the first data into it.

To list all collections in a database:

show collections

The following commands insert 2 documents into a collection called “people”:

khanh = {name : “Khanh”, age : 27}
mai = {name : “Mai”, age : 27, husband : khanh}
db.people.save(khanh)
db.people.save(mai)

To find all documents in collection “people”:

db.people.find()

To find the document with name “Khanh” and update the “age” value:

khanh = db.people.findOne( { name : “Khanh” } )
khanh.age = 28
db.people.save(khanh)

To remove the document with name “Khanh”:

db.people.remove( { name : “Khanh”} )

To remove all documents in collection “people”

db.people.remove()

4. Using MongoDB with other programming languages

Currently, MongoDB support drivers for the following programming languages:

  • C
  • C++
  • Java
  • Javascript
  • Perl
  • PHP
  • Python
  • Ruby

In addition, there are also many community drivers that support almost all programming languages. For more details, please see http://www.mongodb.org/display/DOCS/Drivers

5. References

http://www.mongodb.org

http://en.wikipedia.org/wiki/NoSQL

http://nosql-database.org/

Tagged with:  

Introduction to HTML 5

On August 23, 2010, in Technologies, by khanh


1. Introduction

Recently, there have been a lot of discussions about HTML 5, mainly about how “cool” it is, which features it supports, which browsers support it as well as when it will become popular. Following the trend, this post will also give you a brief introduction about that topic, focusing on some highlighted features that HTML 5 can offer.

html5

2. Getting started with HTML 5

Getting started with HTML 5 is as simple as changing your doctype (which should be the first line of every HTML page). Unlike HTML 4, HTML 5 has only one doctype:

<!DOCTYPE html>

Upgrading to the HTML 5 doctype will not break your existing markup due to the fact that all the tags defined in HTML 4 are still supported in HTML 5. Upgrading to HTML 5 will allow you to use new tags such as <video>, <canvas>, <audio> … However, not all web browsers support all new features provided by HTML5. Fortunately, HTML 5 offer a way to detect if the browser support a particular feature or not by the use of Modernizr, an HTML5 Detection Library.

To use Modernizr, we must declare

<script src=”modernizr.min.js”></script>

within our header

Here is an example to detect if the browser support canvas or not

if (Modernizr.canvas) {
// Canvas is supported
} else {
// Canvas is not supported
}

Use similar code to detect if a specific feature is supported by user’s browser or not.

3. HTML5 highlighted features

3.1. Canvas

By definition, HTML5 canvas is “a resolution-dependent bitmap canvas that can be used for rendering graphs, game graphics, or other visual images”.

You can create a canvas by using the <canvas> tag

<canvas id=”my_canvas” width=”300″ height=”300″></canvas>

That canvas can be accessed in Javascript by:

var canvas = document.getElementById(“my_canvas”);

To draw simple shapes, such as a rectangle:

canvas.fillRect(50, 25, 150, 100);

To draw a line:

var context = canvas.getContext(“2d”);
context.moveTo(0, 0);
context.lineTo(100, 100);

To draw text:

context.font = “bold 12px sans-serif”;
context.textAlign = “right”;
context.fillText(“My Text”, 100, 100);

To draw gradient:

var gradient = context.createLinearGradient(0, 0, 300, 0);
gradient.addColorStop(0, “black”);
gradient.addColorStop(1, “white”);
context.fillStyle = gradient;
context.fillRect(0, 0, 300, 225);

To draw image:

<img id=”image” src=”image.png” />
var image = document.getElementById(“image”);
context.drawImage(image, 0, 0);

Supported browsers: Firefox 3.0+, Safari 3.0+, Chrome 3.0+, Opera 3.0+, iPhone 1.0+, Android 1.0+

3.2. Audio and video

Audio and video features are supported by the <audio> and <video> tags:

<audio src=”audio_file.m4a”></audio>
<video src=”video_file.mp4″></video>

There are many codecs for audio and video. Unfortunately, at the moment, each web browsers supports different type of codec. Here are the details:

  • Firefox 3.5+: Theora+Vorbis+Ogg
  • Safari 3.0+: H.264+AAC+MP4
  • Chrome 5.0+: both Theora+Vorbis+Ogg and H.264+AAC+MP4
  • Opera 10.5+: Theora+Vorbis+Ogg
  • iPhone 3.0+: H.264+AAC+MP4
  • Android 2.0+: H.264+AAC+MP4

To cover more than one browsers, we may want to have different version of the media file using different codecs. The following code show how to support multiple browsers:

<video>
<source src=”video_file.mp4″  type=’video/mp4; codecs=”avc1.42E01E, mp4a.40.2″‘>
<source src=”video_file.webm” type=’video/webm; codecs=”vp8, vorbis”‘>
<source src=”video_file.ogv”  type=’video/ogg; codecs=”theora, vorbis”‘>
</video>

We declare all versions of the video file with the <source> tag. The browser will automatically pick the one that it can understand and play.

3.3. Geolocation

Geolocation is now supported in HTML5. The following code an example of using geolocation:

navigator.geolocation.getCurrentPosition(show_map);
function show_map(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
// Show the map or do something with the location here
}

Supported browsers: Firefox 3.5+, Safari 5.0+, Chrome 5.0+, iPhone 3.0+ and Android 2.0+

3.4. Web Storage

Web Storage is a way for web pages to store named key/value pairs locally, within the client web browser. Like cookies, this data persists even after we navigate away from the web site, close browser tab or exit browser. Unlike cookies, this data is never transmitted to the remote web server.

The following code shows how to use Web Storage:

var first_name = “Khanh”;
localStorage.setItem(“first_name”, first_name);
// …
var k_name = localStorage.getItem(“first_name”);

Supported browsers: IE 8.0+, Firefox 3.5+, Safari 4.0+, Chrome 4.0+, Opera 10.5+, iPhone 2.0+, Android 2.0+

3.5. Web SQL Database (WebDB)

Similar to Web Storage, the Web SQL Database (WebDB) allow web pages to store data locally within the client web browser. The better thing is that WebDB allows data to be stored in relational database and SQL statements can be used to query or update data. If you are familiar with relational database such as SQLite or MySQL, you will find no difficulty when using WebDB.

The following code demonstrates how to use WebDB:

var db = openDatabase(‘mydb’, ’1.0′, ‘my first database’, 2 * 1024 * 1024);
db.transaction(function (tx) {
tx.executeSql(‘CREATE TABLE IF NOT EXISTS foo (id unique, text)’);
tx.executeSql(‘INSERT INTO foo (id, text) VALUES (1, “synergies”)’);
});

Supported browsers: Safari 4.0+, Chrome 4.0+, Opera 10.5+, iPhone 3.0+

3.6. New form input types

HTML5 provides a bunch of new form input types (such as “email”, “url”, “tel” …) that free developers from client-side validation. Here are the new tags supported by HTML5:

  • <input type=”search”> for search boxes
  • <input type=”number”> for spinboxes
  • <input type=”range”> for sliders
  • <input type=”color”> for color pickers
  • <input type=”tel”> for telephone numbers
  • <input type=”url”> for web addresses
  • <input type=”email”> for email addresses
  • <input type=”date”> for calendar date pickers
  • <input type=”month”> for months
  • <input type=”week”> for weeks
  • <input type=”time”> for timestamps
  • <input type=”datetime”> for precise, absolute date+time stamps
  • <input type=”datetime-local”> for local dates and times

4. References:

http://diveintohtml5.org/

http://html5tutorial.net/general/html-5-reference.html

http://simon.html5.org/html5-elements

Tagged with:  


1. Introduction

The fact that Heroku offers free account (Blossom package) is one of the reason why Ruby on Rails developer should try Heroku. However, the limitation of Heroku free account is that its database is limited to only 5MB and this small size is suitable for testing purpose only. Fortunately, you can configure your free Heroku application to use an external database of your choice. By default, Heroku uses PostgreSQL and this document will show you how to instruct your free Heroku application to use an external MySQL database. MySQL is selected because I have a GoDaddy host that supports up to 25 MySQL databases which I can use for my Heroku Rails application. For PostgreSQL, the instruction is very similar.

Database

This entry assumes that you have read the previous post about Heroku and how to use it to host your Rails application.

2. Using external database for Heroku application

By default, Heroku automatically creates a PostgreSQL database for your application. To instruct Heroku to use an external database, we need to configure the var DATABASE_URL. This can be done by:

$ heroku config:add DATABASE_URL=mysql://username:password@host/databasename

Please note that you can replace “mysql” with any other supported database (such as “postgres”)

Since MySQL is not supported by default, we will ask Heroku to install its gem. This can be done by creating a file named “.gems” in the application root folder and put “mysql” as the content. This will ask Heroku to install the mysql gem for our application. Now we push the code to Heroku and rake the database

$ git add .
$ git commit -m “Add .gems file with mysql gem”
$ git push heroku master
$ heroku rake db:migrate

Congratulations! Our free Heroku application is no longer limited to 5MB database.

3. References

http://docs.heroku.com/database

http://blog.supermatter.com/post/702461726/using-a-non-rds-mysql-with-heroku

Tagged with:  
Get Adobe Flash playerPlugin by wpburn.com wordpress themes