• Stars
    star
    124
  • Rank 279,233 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 12 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Lightweight, blazing fast node.js ODM on top of mysql-libmysqlclient

Mapper

Mapper makes 80% of data access easy and provides unobtrusive access to SQL for the 20% complicated, speed-critical tasks.

Motivation

Wanted a lightweight data mapper that is fast and likes SQL.

Install

To use mapper in your project

# For Ubuntu
sudo apt-get install libmysqlclient-dev

npm install mapper

To run Backbone or AngularJS Example

git clone git://github.com/mgutz/mapper.git
cd mapper
npm install -d
make test                   # creates necessary database and config.json
node example/app.js

then browse http://localhost:3000

TODO

Connection pooling - adding SOON

Quickstart

Conect to Database

var Mapper = require('mapper');
var conn = { user: 'grace', password: 'secret', database: 'app_dev' };

// set verbose flag to trace SQL
// set strict to be warned of invalid columns in JSON objects
Mapper.connect(conn, {verbose: true, strict: false});

Define Data Access Objects

// Table name and optional primary key
var Comment = Mapper.map("Comments")
  , Post = Mapper.map("Posts", "id");

Define Relationships

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

Create

var insertId;

// These are equivalent, where first is more SQL like
Post.insert({ title: 'First Post' }).exec(function(err, result) {
    insertId = result.insertId;
});
Post.create({ title: 'First Post' }, function(err, result) { ... });

Retrieve

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

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.affectedRows, 1);
  });

// if doc has id set, then save is simple. Note,
// pluck only the columns you want updated
Post.save(doc, function(err, result) { ... });

Delete

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

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', 'createdAt')
     .order('id DESC')
     .page(1, 50);
  })
  .all(function(err, posts) {
    // boo-yah!
  });

OR, if you prefer SQL

var sql = ("SELECT id, title, excerpt FROM `Posts` \
            ORDER BY id DESC LIMIT 0, 25";

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

SQL goodness

Executing multiple statements in a series

Mapper.client.execSeries(
  "SELECT * FROM posts WHERE author = ?", [1],

  // SQL may be separated by `,`
  "SELECT * ",
  "FROM comments WHERE author = ?", [1],

  function(err, results) {
    // posts are in results[0][0..n]
    // comments are in results[1][0..n]
  }
);

Executing multiple statements in parallel

Mapper.client.execParallel(
  "SELECT * FROM posts WHERE author = ?", [1],
  "SELECT * FROM comments WHERE author = ?", [1],
  function(err, results) {
  }
);

Benchmarks

Time for 100,000 iterations alternating between insert and select. See test/bench or run make bench.

time node test/bench/testMysql.js (mysql 2.0.0-alpha3)

real        1m27.239s
user        0m58.506s
sys         0m3.288s

time node test/bench/testMapperDao.js

real        0m30.701s
user        0m11.346s
sys         0m4.403s

time node test/bench/testLibMysql.js

real        0m26.044s
user        0m8.207s
sys         0m3.784s

time node test/bench/testMongo.js (just for fun)

real        0m41.771s
user        0m30.830s
sys         0m2.910s

The takeaway is mysql-libmysqlclient is a much faster driver than the widely used mysql driver. Mapper, which is based on mysql-libmysqlclient adds overhead yet outperforms the raw mysql driver.

Even more surprising is Mapper is faster than MongoDB using the official MongoDB driver for node.js.

Implementation Best Practice

A simple approach, without over-engineering your project, is to maintain 3 distinct layers in your code:

  1. Data Access Objects (DAO) - Responsible for interacting with the database. There should be 1 DAO for each table used by project.
  2. Models - A model uses one or more DAO adding business logic, validations as needed.
  3. Resources or Services - This layer should only use models never DAO.

On a more complex project where a few tables might be better stored in Redis for example, insert a Repository layer between DAO and models to insulate models completely from low-level data access.

More Repositories

1

dat

Go Postgres Data Access Toolkit
Go
609
star
2

ansi

Small, fast library to create ANSI colored strings and codes. [go, golang]
Go
407
star
3

logxi

A 12-factor app logger built for performance and happy development
Go
352
star
4

vpsbench

Benchmarks VPS perfomance
Shell
321
star
5

execSync

node.js' missing execSync
JavaScript
152
star
6

nanoc3_blog

nanoc3 Blog Starter Kit
Ruby
88
star
7

str

Package str is a string library to build more Go awesomeness
Go
69
star
8

plv8-bedrock

PostgreSQL/plv8 CommonJS, migrations, unit tests. It really kicks the dolphin's ass.
JavaScript
44
star
9

dropwizard-atmosphere

Dropwizard example w/ atmosphere
JavaScript
42
star
10

node-settings

Simple, hierarchical environment-based app settings.
CoffeeScript
21
star
11

sbt-console-template

Get started with Scala with tests and console app using this sbt template.
Scala
20
star
12

mygrate

SQL file based database migrations for MySQL and PostgreSQL
CoffeeScript
17
star
13

goa

Golang assets pipeline
Go
16
star
14

backbone-knockout-examples

Backbone examples ported from Knockout.
JavaScript
14
star
15

vim-colors

My gVim colorschemes.
Vim Script
14
star
16

kohana-wp

Kohana 3 plugin for WordPress.
PHP
11
star
17

Mgutz.DapperPg

.NET 5 WebApi project with Dapper and PostgreSQL
C#
10
star
18

chromeapp

Create desktop apps using Chrome, WebSockets and Go
Go
8
star
19

minimist

port of substack/minimist to golang
Go
8
star
20

sshtunnel

simple go ssh tunnelling
Go
8
star
21

razor

Golang Razor compiled template functions
Go
7
star
22

bake

Bash make utility
Shell
6
star
23

gosu-colors

Dark and light colorscheme for VIM
Vim Script
5
star
24

vertx-web-hello

vert.x intellij run/debug example
Java
5
star
25

funcd

Function based template engine like Builder
JavaScript
5
star
26

owncloud-ssl

Installs ownCloud, an open source DropBox clone, onto a debian server.
4
star
27

mapper-pg

A lightweight PostgreSQL data mapper that likes SQL.
JavaScript
4
star
28

mapper-obtvse

Blog example for Mapper DAO
JavaScript
4
star
29

fsx

Function based JSX. Good for TypeScript, CoffeeScript
JavaScript
4
star
30

inj

KISS, `require` based dependency injection (DI) for node.js
JavaScript
4
star
31

luv

Project build utility like Rake for luvit
Lua
3
star
32

jo

Loosely typed JSON Object
Go
3
star
33

kohana-wp-examples

Kohana-WP WordPress examples
PHP
3
star
34

mgutz-colors

ANSI colors string library for sexy color output.
JavaScript
2
star
35

coffee-cake

Enhanced version of coffee-script's cake build tool
JavaScript
2
star
36

configpipe

Go configuration using a pipeline
Go
2
star
37

postgres-chinook-image

PostgreSQL image with chinook sample data.
Shell
2
star
38

gtk-theme-function

Function Metacity & GTK theme
JavaScript
1
star
39

go-minconf

Golang port of minconf
Go
1
star
40

plv8-mantle

Core for mgutz/plv8-bedrock
JavaScript
1
star
41

task

no config task runner
JavaScript
1
star