Skip to content

Instantly share code, notes, and snippets.

@darkoverlordofdata
Created May 8, 2015 05:59
Show Gist options
  • Save darkoverlordofdata/1dcd44ecd3ccf92dd579 to your computer and use it in GitHub Desktop.
Save darkoverlordofdata/1dcd44ecd3ccf92dd579 to your computer and use it in GitHub Desktop.
Firebase orm
###*
@see http://bish.nu/2014/exposing-firebase-as-ORM-in-nodejs/
###
Firebase = require("firebase")
_ = require("underscore")
###*
Initialize the db (acting as ORM):
orm = require('./firebase-orm')
db = orm('http://myblog.firebaseio.com',
process.env.FIREBASE_AUTH, [ 'posts', 'comments' ])
@param fbPath
@param auth
@param types
@returns {{data: {}}}
###
module.exports = (fbPath, auth, types) ->
fbRoot = new Firebase(fbPath)
db = data: {}
data = db.data
fbRoot.authWithCustomToken auth, (err, a) ->
throw err if err
types.forEach (type) ->
data[type] = {}
data[type].values = []
data[type].ids = []
data[type].cloud = fbRoot.child(type)
data[type].cloud.on "child_added", (snap) ->
remoteItem = snap.val()
stringified = JSON.stringify(remoteItem)
localIndex = data[type].values.length
data[type].values[localIndex] = remoteItem
data[type].ids[localIndex] = snap.name()
return
data[type].cloud.on "child_removed", (snap) ->
remoteItem = snap.val()
stringified = JSON.stringify(remoteItem)
localIds = data[type].ids
localItemIndex = localIds.indexOf(snap.name())
if ~localItemIndex
data[type].values.splice localItemIndex, 1
localIds.splice localItemIndex, 1
return
data[type].cloud.on "child_changed", (snap) ->
remoteItem = snap.val()
stringified = JSON.stringify(remoteItem)
localIds = data[type].ids
localItemIndex = localIds.indexOf(snap.name())
data[type].values[localItemIndex] = remoteItem if ~localItemIndex
return
return
###
Use db.read to read back the full list of objects of a particular resource type:
db.read 'posts', (e, posts) ->
console.log(posts)
@param type
@param fn
###
db.read = (type, fn) ->
values = data[type].values
fn null, values.map((obj, i) ->
id = data[type].ids[i]
_.extend _.clone(obj),
id: id
)
return
###
Use db.create to create new objects of provided resource type:
db.create 'posts',
title: 'Title',
body: 'Body'
, (e, post) ->
id = post.id
console.log('created with id', id)
@param type
@param obj
@param fn
###
db.create = (type, obj, fn) ->
ref = data[type].cloud.push(obj, (e) ->
return fn(e) if e
fn null, _.extend(_.clone(obj),
id: ref.name()
)
return
)
return
###
Use db.update to update a particular object:
db.update 'posts', post.id,
title: 'New title'
, (e, post) ->
console.log('updated', post)
@param type
@param id
@param attributes
@param fn
@returns {*}
###
db.update = (type, id, attributes, fn) ->
info = getResource(data[type], id)
ref = info.ref
obj = info.obj
return fn(new Error("Resource not found in database")) unless obj
_.extend obj, _.omit(attributes, "id")
ref.set obj, (e) ->
return fn(e) if e
fn null, _.extend(_.clone(obj),
id: id
)
return
return
###
Use db.delete to delete a particular object from database:
db.delete 'posts', id, (e, post) ->
console.log('deleted', post)
@param type
@param id
@param fn
@returns {*}
###
db.delete = (type, id, fn) ->
info = getResource(data[type], id)
ref = info.ref
obj = info.obj
return fn(new Error("Resource not found in database")) unless obj
ref.remove (e) ->
return fn(e) if e
fn null, _.extend(_.clone(obj),
id: id
)
return
return
getResource = (dataObj, id) ->
index = dataObj.ids.indexOf(id)
obj = dataObj.values[index]
return {} unless obj
ref: dataObj.cloud.child(id)
obj: obj
return db
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment