def updateMongoDocument(self, jsonDoc, collection=None): # Note for now: We just create a new document. Reason: Simpler """ Updates an existing document, by replacing it with new contents. This function only validates the presence of the required fields. :Preconditions (Otherwise exception is thrown): * isConnected must be true, * required fields must be present :param jsonDoc: Document as a JSON document. The document needs to contain a valid id. :return : If the document to be updated is found, returns the id of the document. If it can not be found, raises an exception. Document content returned (mandatory). Other user fields may be present: :: { _id: Document id as a string @context: Context describing the format of the document } """ if not (collection): collection = self.mongoCollection if (self.isConnected()): if (jsonDoc is None): raise MongoDocumentException(2) if '_id' in jsonDoc: doWithId = self.getMongoDocument(jsonDoc['_id']) if (doWithId is None): # ID cannot be found logger.logInfo(MongoDocumentException(5, jsonDoc['_id'])) raise MongoDocumentException(5, jsonDoc['_id']) else: logger.logInfo(MongoDocumentException(5, "")) raise MongoDocumentException(5, "") mongo_utils.changeDocIdToMongoId(jsonDoc) try: db = self.client[self.mongoDb] coll = db[collection] doc_id = coll.save(jsonDoc) return str(doc_id) except Exception, e: logger.logUnknownError("Annotation Storage Update Document", "", e) raise MongoDocumentException(0)
def __validateDocumentIds(self, documentIds): """ :@param documentIds: List of documents containing the annotations. Raises an exception if documentIds contains an invalid Id (Invalid Format, not whenever it exists or not). :@return: 0 if documentIds is empty. """ if not (type(documentIds) is list): return 0 if (len(documentIds) == 0): return 0 for docId in documentIds: if (not mongo_utils.isObjectId(docId)): logger.logInfo(AnnotationException(3, docId)) raise AnnotationException(3, docId) return 1
def updateAnnotation(self, jsonDoc, strDocId, storageType=1): """ This function updates an annotation. Currently this only works for annotations in storageType = 1. @Preconditions: documentId : A valid storage id. (we don't check that it exists however). strDocId will be added to the annotation object as doc_id (or overwrite existing field). """ if not mongo_utils.isObjectId(strDocId): logger.logInfo(AnnotationException(1, strDocId)) raise AnnotationException(1, strDocId) if (jsonDoc is None): raise MongoDocumentException(2) jsonDoc['doc_id'] = strDocId return self.updateMongoDocument(jsonDoc)
def createAnnotation(self, jsonDoc, strDocId, storageType=1): """ This function creates an annotation. Currently this only works for annotations in storageType = 1 @Preconditions: documentId : A valid storage id. (We don't check that it exists however). documentId will be added to the annotation object as doc_id (or overwrite existing field). For the rest check createMongoDocument(self,jsonDoc,coll). """ self.__validateStorageByType(storageType) if not mongo_utils.isObjectId(strDocId): logger.logInfo(AnnotationException(1, strDocId)) raise AnnotationException(1, strDocId) if (jsonDoc is None): raise MongoDocumentException(2) jsonDoc['doc_id'] = strDocId return self.createMongoDocument(jsonDoc, self.storageCollections[storageType])
def createAnnotationS(self, jsonBatch, strDocId, batchFormat=1, storageType=1): """ Inserts annotations by batch. All annotations must be valid. Raises an error if there is even a single invalid annotation. A valid annotation after processing has the following attributes: :doc_id: Describes the id of the document containing the annotation. Equals to strDocId. :@context: A field linking the context of the document. This field will be automatically created. _id: A unique id identifying the annotation, :@param jsonBatch : JSON of the message. See batch format on how this field is supposed to be structured. :@param strDocId : Id of the document containing the annotation :@param storageType : Describes how to store the elements. (Currently can not be changed) Supports: 1,2 :@param batchFormat : Describes the format of the elements to input. Supports: 0,1 @return: Number of created annotations. """ if (not mongo_utils.isObjectId(strDocId)): logger.logInfo(AnnotationException(1, strDocId)) raise AnnotationException(1, strDocId) self.__validateStorageByType(storageType) # We do not support you can not create in all storages. if (storageType == AnnotationManager.ALL_STORAGE): logger.logError(AnnotationException(7, storageType)) raise AnnotationException(7, storageType) # If the batch doesn't have data if 'data' not in jsonBatch: return 0 if (batchFormat != AnnotationManager.COMPACT_BATCH_FORMAT and batchFormat != AnnotationManager.BASIC_BATCH_FORMAT): logger.logInfo(AnnotationException(5, batchFormat)) raise AnnotationException(5, batchFormat) batchData = jsonBatch['data'] if (batchFormat == AnnotationManager.COMPACT_BATCH_FORMAT): if 'common' in jsonBatch: batchCommon = jsonBatch['common'] # Optimisations later for anno in batchData: for common in batchCommon: anno[common] = batchCommon[common] for anno in batchData: # We don't want the client to specify an id. if '_id' in anno: del anno["_id"] if (self.isConnected()): try: #make each annotation reference its document for anno in batchData: anno['doc_id'] = strDocId db = self.client[self.mongoDb] coll = db[self.storageCollections[storageType]] if (storageType == 1): # Insert annotations one by one. nbAnnoToInsert = len(batchData) nbInserted = len(coll.insert(batchData)) if (nbAnnoToInsert != nbInserted): # TODO: Delete all annotations if this happens raise AnnotationException(8, nbInserted, nbAnnoToInsert) return nbInserted else: #Batch storage, save as files fs = gridfs.GridFS(db) batchDoc = {} for anno in batchData: if ( batchDoc == {} ): #Possible common attributes between annotations. for attrib in anno: batchDoc[attrib] = anno[attrib] # IF an annotation have a different value for an attribute, then the # common attribute, the common attribute must be deleted. for attrib in anno: if (str(attrib) in batchDoc): if (anno[attrib] != batchDoc[str(attrib)]): del batchDoc[attrib] #Add id anno["id"] = str(ObjectId()) jsonDump = simplejson.dumps(batchData) annoFileID = fs.put(jsonDump) nbInserted = len(batchData) if 'common' in jsonBatch: batchCommon = jsonBatch['common'] for common in batchCommon: batchDoc[common] = batchCommon[common] batchDoc['doc_id'] = str(strDocId) batchDoc['file_fs_id_batch'] = annoFileID try: batch_id = coll.insert(batchDoc) except Exception, e: #clean up file info so we dont have garbage in our db logger.logUnknownError( "Annotation Storage Create Annotations", "", e) fs.delete(annoFileID) raise MongoDocumentException(0) return nbInserted except AnnotationException, e: logger.logError(e) raise e except Exception, e: logger.logUnknownError("Annotation Storage Create Annotations", "", e) raise MongoDocumentException(0)