Skip to content

Instantly share code, notes, and snippets.

@mizchi
Created April 19, 2014 07:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mizchi/11077275 to your computer and use it in GitHub Desktop.
Save mizchi/11077275 to your computer and use it in GitHub Desktop.
Momic = {}
class Momic.Collection
constructor: (@key, {@schema, @hasInstance, @hasPersistence, @endpoint, @autoSave}) ->
@autoSave ?= true
@hasPersistence ?= true
@hasInstance ?= true
unless @hasPersistence or @hasPersistence
throw new Error('hasInstance or hasPersistence must be true')
@_count = 0
@_instance = null
_updateCount: (@_count) =>
count: => @_count
load: => localforage.getItem(@key)
loadWithParse: => new Promise (done) =>
@load (content) =>
try
done(JSON.parse(content))
catch e
throw 'Parse error: '+content
loadContent: => new Promise (done) =>
if @hasInstance then done @_instance
else @loadWithParse().then (content) => done(content)
findOne: => new Promise (done) =>
(@find.apply @, arguments).then (results) => done(results[0])
save: (content = null) => new Promise (done) =>
throw "`#{@key}` collection doesn't have storage" unless @hasPersistence
tosave = content ? @_instance
localforage.setItem(@key, JSON.stringify(tosave)).then =>
# debugger
@resolved = true
done()
insert: (obj) => new Promise (done) =>
array = if obj.length? then obj else [obj]
@loadContent().then (content) =>
# TODO: check shema
content.push i for i in array
@_updateCount(content.length)
# debugger
if @autoSave
console.log 'autoSaving'
@save().then => done()
else
@resolved = false
done()
drop: => new Promise (done) =>
localforage.removeItem(@key).then => done()
dequal = (obj, target) ->
isPrimitive = (typeof obj) in ['string', 'number', 'boolean', 'undefined']
if isPrimitive then return (obj is target)
results =
if obj instanceof Array
for i in obj
dequal(obj[i], target[i])
else if obj instanceof Object
for key, val of obj
dequal(obj[key], target[key])
(results.filter (item) -> item).length > 0
find: (func_or_obj = null) => new Promise (done, reject) =>
@loadContent.then (content) =>
results =
if not func_or_obj
content
else if func = func_or_obj instanceof Function
content.filter (item) => func(item)
else if queryObj = func_or_obj instanceof Object
content.filter (item) => dequal(queryObj, item)
done(resutls)
init: => new Promise (done) =>
localforage.getItem(@key).then (content) =>
if content?
try
cottent = JSON.parse(content)
catch e
throw "#{@key} is not used as momic repository"
else
content ?= []
@_instance = content if @hasInstance
if @hasPersistence
@save(content).then => done()
else
@_updateCount(content.length)
done()
class Momic.DB
collectionKey: (collectionName) =>
@prefix + '-' + collectionName
constructor: (opts) ->
@initialized = false
@prefix = opts.name
@storage = opts?.storage or 'localforage'
@collections =
for key, colOpts of opts.collections
colOpts.storage ?= @storage
@[key] = new Momic.Collection(@collectionKey(key), colOpts)
init: => new Promise (done) =>
inits = @collections.map (col) -> col.init()
Promise.all(inits).then =>
@initialized = true
done()
window.db = new Momic.DB
name: 'app'
storage: 'localforage' # default localforage
collections:
items:
# if hasInstance true, find becomes fast but has pressure to memory
hasInstance: true # default true
# if hasPersistence true, storage it.
# hasInstance or hasPersistence must be true.
hasPersistence: true # default
storage: 'localforage' # default is db's storage
autoSave: true
schema:
itemType: String
name: String
value: Number
db.items.drop().then =>
db.init().then =>
a = db.items.insert({itemType: 'weapon', name: 'ひのきのぼう', value: 10})
# a.then (a) =>
# debugger
# console.log a
# , => console.log 'insert fail'
# , => console.log 'init fail'
# , => console.log 'drop fail'
# b = db.items.insert([
# { itemType: 'weapon', name: 'てつのつるぎ', value: 50}
# { itemType: 'weapon', name: 'はがねのつるぎ', value: 120}
# ])
# Promise.all(a,b).then =>
a.then =>
debugger
console.log db.items.count() #=> 3
db.items.findOne({name: 'てつのつるぎ'}).done (item) => console.log item
db.items.find((item) -> item.value > 30).done (items) =>
db.drop({value: {'$gte':30}}).done (items) =>
console.log 'items that has value more thant 30 area removed'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment