Przeglądaj źródła

recursive save and recursive lazy load

Ivan Asmer 6 lat temu
rodzic
commit
56f1d87b19
2 zmienionych plików z 70 dodań i 24 usunięć
  1. 24 3
      index.js
  2. 46 21
      mm.js

+ 24 - 3
index.js

@@ -1,4 +1,5 @@
 const MongoClient = require("mongodb").MongoClient;
+const ObjectID    = require("mongodb").ObjectID;
 const mm          = require('./mm.js')
 const delay       = ms => new Promise(r => setTimeout(r.bind(ms), ms))
  
@@ -43,16 +44,36 @@ const delay       = ms => new Promise(r => setTimeout(r.bind(ms), ms))
     //}
 
     let person = new Savable()
-    person._id = '5c79f5a952dd4e30b3e65a37';
+    person._id = ObjectID('5c7bd603ce3cbc409978203e');
     console.log(person)
+
+    let child = new Savable({
+        name: 'New One Child',
+        surname: 'Silniy',
+        phones: ['105', '1000506']
+    });
+
+    console.log(await person)
+    console.log(await person.children[10])
+    console.log(await person.children[10].father)
+    console.log(await person.children[10].father.children[9])
+    //console.log(await person.children[1])
+    ;(await person).children.push(child)
+    child.father = person
+
+    //console.log(person)
+    //console.log(child)
+
+    await person.save()
+
     //let obj = {
         //then(cb){
             //process.nextTick(() => cb(obj))
         //}
     //}
     //console.log(await obj)
-    console.log('empty await', await person)//.then(p => console.log(p))
-    console.log('sub await', (await person.children[0]))//.then(p => console.log(p))
+    //console.log('empty await', await person)//.then(p => console.log(p))
+    //console.log('sub await', (await person.children[0]))//.then(p => console.log(p))
 
 
 

+ 46 - 21
mm.js

@@ -1,24 +1,39 @@
-const ObjectID  = require('mongodb').ObjectID
-
+const ObjectID    = require("mongodb").ObjectID;
 module.exports = db => {
     class Savable {
-        constructor(obj){
-            console.log('CONSTRUCTOR')
+        constructor(obj, empty=false){
             this._id    = null
             this._class = this.__proto__.constructor.name
             this._empty = true
 
-            Savable.classes = Savable.classes || []
-            Savable.classes.push(this.__proto__.constructor)
+            Savable.classes                                  = Savable.classes || {}
+            Savable.classes[this.__proto__.constructor.name] = this.__proto__.constructor
 
-            this.populate(obj)
+            if (obj){
+                this.populate(obj)
+                this._empty = empty
+            }
         }
 
-        populate(obj){
-            if (obj){
-                for (const key in obj) this[key] = obj[key]
-                this._empty = false
+
+
+        populate(obj, empty){
+            function convertSavables(obj){
+                for (const key in obj){
+                    if (Savable.isSavable(obj[key])){
+                        obj[key] = Savable.newSavable(obj[key])
+                    }
+                    else if (typeof obj[key] === 'object'){
+                        convertSavables(obj[key])
+                    }
+                }
             }
+
+
+
+            for (const key in obj) this[key] = obj[key]   
+
+            convertSavables(this)
         }
 
         get _empty(){
@@ -33,10 +48,10 @@ module.exports = db => {
                         return this
                     }
                     delete this.then
-                    if (!this._id) err(new ReferenceError('Id is empty'))
+                    if (!this._id)    err(new ReferenceError('Id is empty'))
                     if (!this._class) err(new ReferenceError('Class is empty'))
 
-                    this.collection.findOne({_id: ObjectID(this._id)}).then( data => {
+                    this.collection.findOne({_id: this._id}).then( data => {
                         if (!data){
                             err(new ReferenceError('Document Not Found'))
                         }
@@ -64,12 +79,11 @@ module.exports = db => {
                     if (obj[key] && typeof obj[key] === 'object'){
                         if (obj[key] instanceof Savable){
                             if (!(obj[key]._id)){
-                                await obj[key].save()
+                                await obj[key].save().catch(err => console.log('ERR', ERR))
                             }
                             result[key] = {_id: obj[key]._id, _class: obj[key]._class}
                         }
                         else {
-                            console.log('recursion', obj, key)
                             result[key] = await recursiveSlicer(obj[key])
                         }
                     }
@@ -80,18 +94,29 @@ module.exports = db => {
                 return result;
             }
 
-            const toSave = await recursiveSlicer(this)
-            console.log(toSave)
+            const {_id, _empty, then, ...toSave} = await recursiveSlicer(this)
 
             if (!this._id){ //first time
-                delete toSave._id
-                delete toSave._empty
                 const { insertedId } = await this.collection.insertOne(toSave)
                 this._id = insertedId
             }
-            else { //updateOne
-                this.collection.updateOne(toSave, {_id: this._id})
+            else { //update
+                await this.collection.updateOne({_id: this._id},  {$set: toSave}).catch(err => console.log('UPDATE ERR', err))
+            }
+        }
+
+        static isSavable(obj){
+            //console.log(obj._id, obj._class)
+            return obj && obj._id && obj._class
+        }
+
+        static newSavable(obj){
+            let className = obj._class || "Savable"
+            if (obj instanceof Savable.classes[className]){
+                return obj
             }
+            
+            return new Savable.classes[className](obj, true)
         }
     }
     return Savable