mapper-pg

A lightweight PostgreSQL data mapper that likes SQL.

npm install mapper-pg
5 downloads in the last month

Mapper-pg

A lightweight PostgreSQL data mapper that likes SQL.

Install

To install

npm install mapper-pg --save

To test it

npm install -d
make test

To run Backbone example

make test             # creates the necessary database and table
node example/app.js   # runs the server, browse http://localhost:3000

TODO

  • Transaction support

Documentation

See comprehensive tests in test/integration/integrationTest.js.

Quickstart

Require it

var Mapper = require('mapper-pg');

Define Data Access Objects (DAO) for each table

// simple, only table name with optional primary key
var Comment = Mapper.map('Comments');
var Post = Mapper.map('Posts', 'id');

Define relationships beetween DAOS, see lib/relation.js

Post.hasMany('comments', Comment, 'postId');
Comment.belongsTo('post', Post, 'postId');

Initialize

// set `verbose`  to trace SQL, set `strict` for invalid column warnings
var config = { user: 'boo', password: 'secret', database: 'app_dev', verbose: true, strict: false };

Mapper.initialize(config, function(err) {
    // setup express, etc
});

CRUD Examples

Create

var insertId;

// insert a new post
Post.insert({title: 'First Post'}).exec(function(err, result) {
    insertId = result.id;
});

// OR sugar
Post.create({title: 'First Post'}, function(err, result) {
    insertId = result.id;
});

Retrieve

// select inserted post
Post.where({id: insertId}).one(function(err, post) {
    assert.equal(post.title, 'First Post,');
});

// OR sugar
Post.findById(insertId, function(err, post) {});

Update

// update inserted post
Post
  .update()                         // optional since set() is used
  .set({title: 'New Title'})
  .where({id: insertId})
  .exec(function (err, result) {
    assert.equal(result.rowCount, 1);
  });

// OR sugar, updates based on id
Post.save({title: 'New Title', id: insertId}, function(err, result) {});

Delete

// delete all posts with a specific title
Post.delete().where({title: 'New Title'}).exec(function(err, result) {
    assert.equal(result.rowCount, 1);
});

// OR sugar
Post.deleteById(insertId, function(err, result) {});

Gets the first page of posts and populate comments property with the second page of comments for each post retrieved.

Post
  .select('id', 'title', 'excerpt')
  .page(0, 25)
  .order('id DESC')
  .load('comments', function(c) {
    c.select('comment', 'created_at')
     .order('id DESC')
     .page(1, 50);
  })
  .all(function(err, posts) {
    // boo-yah!
  });

Or, mix SQL

var sql = ('SELECT id, title, excerpt FROM Posts ORDER BY id DESC LIMIT 25';

Post.all(sql, function(err, posts) {
  Post.load('comments', function(c) {
    c.sql('SELECT comment, createdAt FROM Comments ORDER BY id DESC LIMIT 50 OFFSET 50');
  }).in(posts, function(err) {
    // boo-yah!
  });
});

SQL goodness

Execute multiple statements in a series

Mapper.client.series([
  'SELECT * FROM posts WHERE author = ?;', [1],

  // use commas to break up SQL
  'SELECT * ',
  'FROM comments WHERE author = ?;', [1]
], function(err, results) {
    // posts are in results[0][0..n]
    // comments are in results[1][0..n]
});

Execute multiple statements in parallel

Mapper.client.parallel([
  'SELECT * FROM posts WHERE author = ?;', [1],
  'SELECT * FROM comments WHERE author = ?;', [1],
], function(err, results) {
    //...
});
npm loves you