Example #1
0
    def test_nextid_id_empty_collection(self):
        '''Doc this
            '''
        db = self.g['db']
        generic = controllers.Generic(self.g)
        coll = db['cnts']

        response = nextId(coll)

        assert response['status'] == 200
        assert response['nextId'] == 1
Example #2
0
    def test_nextid_id_empty_collection(self):
        """Doc this
            """
        db = self.g["db"]
        generic = controllers.Generic(self.g)
        coll = db["cnts"]

        response = nextId(coll)

        assert response["status"] == 200
        assert response["nextId"] == 1
Example #3
0
    def post(self, **kwargs):
        '''Insert a doc
            newDocTmp: Initialize a temp (tmp) doc if no OID and no data.
            cloneDocTmp: Clone to a temp doc if OID and no isTmp flag set.
            upsertDocTmp: Update or Insert temp doc to base collection if OID and isTmp is set.
            insertDoc: Insert a new doc if no OID and there are more attributes than _c.
            '''
        db           = self.db
        
        response     = {}
        docs         = []
        status       = 200
        
        usrOID       = self.usr['OID']
        docs_to_post = kwargs['docs']
        
        post_errors  = []
        total_errors = 0

        for doc in docs_to_post:
            errors      = {}
            doc_info    = {}

            # required attribute
            _c          = doc['_c']

            # shortcut
            doc_keys   = doc.keys()     
            
            modelClass = getattr(models, _c)
            _id        = doc['_id'] if '_id' in doc_keys else None
            where      = {'_id': ObjectId(_id)} if _id else None
            attrNam    = doc['attrNam'] if 'attrNam' in doc_keys else None
            attr_c     = doc['attr_c'] if attrNam else None
            attrVal    = doc['attrVal'] if attrNam else None
            collNam    = modelClass.meta['collection']
            collTmp    = db[collNam + '_tmp']
            coll       = db[collNam]

            # if _ id is passed,  it directs that a temp doc be initialized and inserted into the appropriate Tmp (temp) collection.
            # if an _id IS passed, it directs that the doc passed in be validated and inserted in the base collection and the temp doc in the temp collection be deleted.
            
            # if attrNam, posting a new value to a listtype attribute/field
            if attrNam:
                for elem in attrVal:
                    modelClass = getattr(models.embed, attr_c)
                    model      = modelClass()
                    for k,v in elem.iteritems(): setattr(model, k, v)
                    
                    resp       = nextEId(doc, attrNam)
                    doc        = resp['doc']
                    # model.eIds = doc['eIds']
                    model.eId  = resp['eId']
                    
                    if hasattr(model, 'vNam') and 'dNam' in model._fields and not model.dNam:
                        model.dNam = model.vNam

                    # generate a slug if slug is empty
                    if 'slug' in model._fields and 'dNam' in model._fields and not model.slug:
                        model.slug = slugify(model.dNam, coll)

                    # set dNamS if used:
                    # if dNamS is empty, set to value of slug
                    if 'dNamS' in model._fields and not model.dNamS:
                        if hasattr(model, 'vNamS'):
                            model.dNamS = model.vNamS
                        else:
                            model.dNamS = model.slug


                    embedDoc   = doc_remove_empty_keys(to_python(model, allow_none=True))
                    doc_errors = validate(modelClass, embedDoc)
                    
                    if doc_errors:
                        total_errors += doc_errors['count']
                        post_errors.append(doc_errors)
                        continue                    
                    
                    embedDoc['_c'] = attr_c
                    
                    # logit update
                    embedDoc = logit(self.usr, embedDoc, method='post')
                    
                    collTmp.update(where,
                            {"$push": { attrNam: embedDoc}, "$set": {'eIds': doc['eIds']}}
                        )
                    

                    doc_info['doc']   = embedDoc
                    docs.append(doc_info)   
                               
                # http://docs.mongodb.org/manual/applications/update/
                # { $set: { 'emails.$.eId': 2 }
        
                response['total_inserted'] = len(docs)
        
                if post_errors:
                    response['total_invalid'] = len(post_errors)
                    response['errors']        = post_errors
                    response['total_errors']  = total_errors
                    status                    = 400
                else:
                    response['total_invalid'] = 0
        
                response['docs'] = docs
        
                return {'response': response, 'status': status}                
                
            # Initialize a temp (tmp) doc if no OID and no data.
            elif not '_id' in doc_keys and len(doc_keys) == 1:
                newDocTmp = True
                useTmpDoc = True
                
            # Clone to a temp doc if OID and no isTmp flag set.
            elif '_id' in doc_keys and not 'isTmp' in doc_keys and len(doc_keys) > 2:
                cloneDocTmp  = True
                useTmpDoc    = True
                
                
                # find source doc
                # set locked = True                
                doc_cloned = coll.find_and_modify(
                    query = {'_id':_id},
                    update = {"$set": {'locked': True}},
                    new = True
                )                
                # set cloned doc in tmp collection isTmp = True  
                doc_cloned['isTmp'] = True
                
                # don't need locked set in tmp doc 
                del doc_cloned['locked']
                
                # clone/save doc to tmp collection

                # TODO properly handle exception
                try:
                    collTmp.insert(doc_cloned)
                except:
                    pass                  
                        
                doc_info['doc']   = doc_cloned
                
                # TODO
                # should return a link to object according to good practice
                #doc_info['link'] = get_document_link(class_name, id)
    
                docs.append(doc_info)   
                
                continue
                
            # Update temp doc to base collection if OID and isTmp is set.
            elif '_id' in doc_keys and 'isTmp' in doc_keys and doc['isTmp']:
                upsertDocTmp  = True
                useTmpDoc     = False

                tmp_doc = collTmp.find_one({'_id': _id})
                
                # unset isTmp
                _id = tmp_doc['_id']
                tmp_doc['locked'] = False
                del tmp_doc['_id']             
                del tmp_doc['isTmp']             
                
                # logit update
                tmp_doc = logit(self.usr, tmp_doc)
                
                # update original/source doc
                doc = coll.update({'_id': _id}, {"$set": tmp_doc}, upsert=True, safe=True)
                
                # remove tmp doc
                collTmp.remove({'_id': _id})
                
                # though not necessary, to be consistant, return full doc
                doc = coll.find_one({'_id': _id})
                
                doc_info['doc']   = doc  
                docs.append(doc_info)  
                
                continue
                
            # Insert a new doc if no OID and there are more attributes than _c.
            elif not '_id' in doc_keys and len(doc_keys) > 2:
                insertDoc  = True
                useTmpDoc  = False
            
            # need to cruz through all doc keys to handle arrays/listtype fields.
            # they need to be initialized according to the appropriate model and validated, etc.
            doc = initDocListTypes(doc, self.usr)

            # init model instance
            model       = modelClass(**doc)
            
            # set isTemp
            model.isTmp = useTmpDoc and 'isTmp' in model._fields

            # try to generate dNam
            # if there is a vNam class property 
            # if already has a value, use it
            if hasattr(model, 'vNam') and not useTmpDoc and 'dNam' in model._fields and not model.dNam:
                model.dNam = model.vNam

            # assign dId
            if 'dId' in model._fields and not model.dId:
                response = nextId(coll)
                if response['status'] == 200:
                    model.dId = response['nextId']
                else:
                    # handle error condition
                    pass

            # generate a slug if:
            # not a temp doc and slug is empty
            if 'slug' in model._fields and not useTmpDoc and not model.slug:
                model.slug = slugify(model.dNam, coll)

            # set dNamS if used:
            # not a temp doc and dNamS is empty, set to value of slug
            if 'dNamS' in model._fields and not useTmpDoc and not model.dNamS:
                model.dNamS = model.slug

            # do not validate if using temp doc
            if not useTmpDoc:
                doc_errors = validate(modelClass, doc)
                
                if doc_errors:
                    total_errors += doc_errors['count']
                    post_errors.append(doc_errors)
                    continue

            # modelClass stuffed in all available fields
            # let's remove all empty fields to keep mongo clean.
            doc             = to_python(model, allow_none=True)

            # do not log if using temp doc
            #log date time user involved with this event
            if not useTmpDoc:
                doc = logit(self.usr, doc, 'post')

            doc['_c'] = _c
            doc_clean = doc_remove_empty_keys(doc)
            
            # posting an existing temp doc to base collection
            if _id:
                doc_clean['_id'] = str(_id)
                id = str(coll.insert(doc_clean))
                # TODO properly handle exception
                try:
                    collTmp.remove({'_id': _id})
                except:
                    pass

            # posting initialized temp doc
            else:
                # TODO properly handle exception
                try:
                    coll.insert(doc_clean)
                except:
                    pass                  
                    
            doc_info['doc']   = doc_clean
            
            # TODO
            # should return a link to object according to good practice
            #doc_info['link'] = get_document_link(class_name, id)

            docs.append(doc_info)

        response['total_inserted'] = len(docs)

        if post_errors:
            response['total_invalid'] = len(post_errors)
            response['errors']        = post_errors
            response['total_errors']  = total_errors
            status                    = 400
        else:
            response['total_invalid'] = 0

        response['docs'] = docs

        return {'response': response, 'status': status}