Showing posts with label database. Show all posts
Showing posts with label database. Show all posts

Tuesday, 19 February 2013

Install MongoDB for PHP on Mac OS X


MongoDB is a document-oriented database (among other things), and it’s especially convenient that the native document format is JSON. For various ongoing pet projects, I figured I’d give it a try to avoid the overhead of creating/maintaining schemas and having to flatten down my JSON objects to fit a relational model.
These instructions work for 10.7 Lion, 10.6 Snow Leopard and 10.5 Leopard. The steps outlined here ensure that your MongoDB installation integrates well with the rest of the system (Apache, PHP & launchd), is started automatically when the machine starts up, and makes it easy to upgrade later.
There are a lot of conflicting instructions on the Web about how to install MongoDB, and they’re either incomplete (most of them skip the part about making MongoDB run automatically at startup), and none of them satisfied the following requirements I had:
  • I should not need to install any software that’s already present on a stock Mac OS X installation (Lion, Snow Leopard or Leopard, at the very least.)
  • It should be relatively easy to upgrade the base version of MongoDB, so installing it via a package manager would be preferable to installing it from source.
  • The MongoDB server should be started up automatically through system-standard tools such as launchd — not manually every time I need to test something.
This tutorial assumes a virgin Mac OS X installation. If you already have a component installed, simply skip that step.
  1. Install XCode from the Mac App Store. It’s needed for MacPorts.
  2. Install MacPorts from macports.org. MacPorts is a package manager for Mac OS X that makes it easy to install and configure a lot of open-source software.
    Although MongoDB binaries are available from the MongoDB web site, I strongly recommend using the MacPorts MongoDB port. MacPorts ensures dependencies are installed correctly, and provides an easy way to upgrade all outdated packages at once.

Install and configure MongoDB

  1. Install MongoDB. Open a Terminal, ensure you’re using an account with Administrator privileges, and type:
    sudo port install mongodb
    That’s it, MongoDB is now installed. But there’s lots more to do to get it working.
  2. Create directories required by MongoDB.
    # The data directory. sudo mkdir -p /var/lib/mongodb/ # The logs directory. sudo mkdir -p /var/log/mongodb/
  3. Create a config file. Put this in a new file at /etc/mongodb.conf:
# This is an example config file for MongoDB. # Place it at /etc/mongodb.conf # Based on a sample provided at # http://www.mongodb.org/display/DOCS/File+Based+Configuration dbpath = /var/lib/mongodb bind_ip = 127.0.0.1 noauth = true

  1. Configure a launchd LaunchDaemon. Put this in a new file at/Library/LaunchDaemons/org.mongo.mongod.plist.
    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>org.mongodb.mongod</string> <key>ProgramArguments</key> <array> <string>/opt/local/bin/mongod</string> <string>run</string> <string>--config</string> <string>/etc/mongodb.conf</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>WorkingDirectory</key> <string>/var/log/mongodb/</string> <key>StandardErrorPath</key> <string>/var/log/mongodb/output.log</string> <key>StandardOutPath</key> <string>/var/log/mongodb/output.log</string> </dict> </plist>
  2. Start MongoDB via launchd. Type in a Terminal window:
    sudo launchctl load /Library/LaunchDaemons/org.mongo.mongod.plist
You can stop reading now if all you need is MongoDB and don’t plan to use PHP with it. The MongoDB server will be automatically launched at startup.

Enable Apache and PHP5

  1. Start Apache. In System Preferences, go to Sharing, and then check the box next to “Web Sharing”.
  2. Enable PHP5 support in Apache. Open the Apache config file, /etc/apache2/httpd.conf, and locate the following line.
    # LoadModule php5_module
    Uncomment that line, so it reads:
    LoadModule php5_module
  3. Restart Apache. Type in a Terminal window:
    sudo apachectl graceful
  4. Test if PHP is working correctly. Create a new PHP file at/Library/WebServer/Documents/phpinfo.php and put in it:
    <?php phpinfo(); ?>
    Browse to http://localhost/phpinfo.php, and you should see a long page showing your PHP configuration.
    Apache and PHP5 are now configured.

Install and Configure the PHP5 MongoDB driver.

  1. Install PEAR. PEAR is the PHP Extension and Application Repository, from which we’ll install the PHP5 MongoDB driver.
    $ cd /tmp $ wget http://pear.php.net/go-pear.phar $ sudo php -d detect_unicode=0 go-pear.phar
    You’ll be prompted with a default file layout. I changed this to install it in /usr/local/pear instead of under /Users/Admin.
    Below is a suggested file layout for your new PEAR installation. To change individual locations, type the number in front of the directory. Type 'all' to change all of them or simply press Enter to accept these locations. 1. Installation base ($prefix) : /Users/Admin/pear 2. Temporary directory for processing : /tmp/pear/install 3. Temporary directory for downloads : /tmp/pear/install 4. Binaries directory : /Users/Admin/pear/bin 5. PHP code directory ($php_dir) : /Users/Admin/pear/share/pear 6. Documentation directory : /Users/Admin/pear/docs 7. Data directory : /Users/Admin/pear/data 8. User-modifiable configuration files directory : /Users/Admin/pear/cfg 9. Public Web Files directory : /Users/Admin/pear/www 10. Tests directory : /Users/Admin/pear/tests 11. Name of configuration file : /Users/Admin/.pearrc 1-11, 'all' or Enter to continue:
    At this prompt, type 1
    (Use $prefix as a shortcut for '/Users/Admin/pear', etc.) Installation base ($prefix) [/Users/Admin/pear] :
    At this prompt, type /usr/local/pear
    Below is a suggested file layout for your new PEAR installation. To change individual locations, type the number in front of the directory. Type 'all' to change all of them or simply press Enter to accept these locations. 1. Installation base ($prefix) : /usr/local/pear 2. Temporary directory for processing : /tmp/pear/install 3. Temporary directory for downloads : /tmp/pear/install 4. Binaries directory : /usr/local/pear/bin 5. PHP code directory ($php_dir) : /usr/local/pear/share/pear 6. Documentation directory : /usr/local/pear/docs 7. Data directory : /usr/local/pear/data 8. User-modifiable configuration files directory : /usr/local/pear/cfg 9. Public Web Files directory : /usr/local/pear/www 10. Tests directory : /usr/local/pear/tests 11. Name of configuration file : /Users/Admin/.pearrc 1-11, 'all' or Enter to continue:
    At this prompt, type 11
    (Use $prefix as a shortcut for '/usr/local/pear', etc.) Name of configuration file [/Users/Admin/.pearrc] :
    At this prompt, type /etc/pearrc
    Below is a suggested file layout for your new PEAR installation. To change individual locations, type the number in front of the directory. Type 'all' to change all of them or simply press Enter to accept these locations. 1. Installation base ($prefix) : /usr/local/pear 2. Temporary directory for processing : /tmp/pear/install 3. Temporary directory for downloads : /tmp/pear/install 4. Binaries directory : /usr/local/pear/bin 5. PHP code directory ($php_dir) : /usr/local/pear/share/pear 6. Documentation directory : /usr/local/pear/docs 7. Data directory : /usr/local/pear/data 8. User-modifiable configuration files directory : /usr/local/pear/cfg 9. Public Web Files directory : /usr/local/pear/www 10. Tests directory : /usr/local/pear/tests 11. Name of configuration file : /etc/pearrc 1-11, 'all' or Enter to continue:
    At this prompt, type <Enter>
    Would you like to alter php.ini </private/etc/php.ini>? [Y/n] :
    At this prompt, type Y.
  2. Install the PHP MongoDB driver.
    sudo /usr/local/pear/bin/pecl install mongo
  3. Configure the system PHP to load that extension. Add this line to your php.ini. (If you don’t know where your php.ini file is located, go back to the phpinfo page that you created earlier, and you’ll find it on that page.)
    extension=mongo.so
  4. Restart Apache. To enable PHP5 with MongoDB support, restart Apache.
    sudo apachectl graceful

Test your installation.

  1. Create a simple test script. Create a PHP file at /Library/WebServer/Documents/mongodb.php
    <?php $mongoDB = new Mongo(); $database = $mongoDB->selectDB("example"); $collection = $database->createCollection('TestCollection'); $collection->insert(array(test => 'Test OK')); $retrieved = $collection->find(); foreach ($retrieved as $obj) { echo($obj['test']); } ?>
  2. Test the installation. Browse to http://localhost/mongodb.php. If you see the following output, then congratulations, MongoDB is properly installed and configured to work with PHP on your Mac. Happy developing!
    Test OK

Wednesday, 6 February 2013

JDBI : A SQL convenience library for Java



JDBI exposes relational database access in idiommatic Java, using collections, beans, and so on, while maintaining the same level of detail as JDBC. It exposes two different style APIs, a fluent style and a sql object style.

Fluent API

The fluent style looks like:

// using in-memory H2 database
DataSource ds = JdbcConnectionPool.create("jdbc:h2:mem:test",
"username",
"password");
DBI dbi = new DBI(ds);
Handle h = dbi.open();
h.execute("create table something (id int primary key, name varchar(100))");
h.execute("insert into something (id, name) values (?, ?)", 1, "Brian");
String name = h.createQuery("select name from something where id = :id")
.bind("id", 1)
.map(StringMapper.FIRST)
.first();
assertThat(name, equalTo("Brian"));
h.close();

The DBI type is analogous to a JDBC DataSource, and will usually be constructed by passing in a JDBC DataSource. There are alternate constructors which take JDBC URL and credentials, and other means. From the DBI instance you obtain Handle instances. A Handle represents a single connection to the database. Handles rely on an underlying JDBC connection object.
With a handle you may create and execute statements, queries, calls, batches, or prepared batches. In the above example we execute a statement to define a table, execute another statement, this time with two positional arguments to insert a value, and finally construct a query, bind a value to a named argument in the query, map the results to a a String, and take the first result which comes back.
The named argument facility on statements and queries is provided by JDBI – it parses out the SQL and uses positional parameters when actually constructing the prepared statements. 

SQL Object API

The second, SQL object, style API simplifies the common idiom of creating DAO objects where a single method maps to a single statement. A SQL object definition is an annotated interface, such as:

public interface MyDAO
{
@SqlUpdate("create table something (id int primary key, name varchar(100))")
void createSomethingTable();
@SqlUpdate("insert into something (id, name) values (:id, :name)")
void insert(@Bind("id") int id, @Bind("name") String name);
@SqlQuery("select name from something where id = :id")
String findNameById(@Bind("id") int id);
/**
* close with no args is used to close the connection
*/
void close();
}

This interface defines two updates, the first to create the same table as in the fluent api example, and the second to do the same insert, the third defines a query. In the second two cases, notice that the arguments to the statements are past to the method, and bound by name.
The final method, close(), is special. When it is invoked it will close the underlying JDBC connection. The method may be declared to raise an exception, such as the close() method does on java.io.Closeable, making it suitable for use with automatic resource management in Java 7.
To use this sql object definition, we use code like so:

// using in-memory H2 database via a pooled DataSource
JdbcConnectionPool ds = JdbcConnectionPool.create("jdbc:h2:mem:test2",
"username",
"password");
DBI dbi = new DBI(ds);
MyDAO dao = dbi.open(MyDAO.class);
dao.createSomethingTable();
dao.insert(2, "Aaron"); String name = dao.findNameById(2); assertThat(name, equalTo("Aaron")); dao.close(); ds.dispose();

We obtain an instance of the sql object from the DBI instance, and then call methods on it. There are a couple different ways of creating sql object instances. The one one here binds the object to a specific handle, so we need to make sure to close the object when we are finished with it.