def deleteMongoDocument(self, strDocId, collection=None): """ Deletes a document specified by ID. :param strDocId: Document ID as string. Should be unique. :returns: 0 if no elements were deleted, 1 if one was deleted. """ if not mongo_utils.isObjectId(strDocId): return 0 return self.deleteMongoDocumentS({"_id": ObjectId(strDocId)}, collection)
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 = json.dumps(batchData).encode("UTF-8") 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 as 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 as e: logger.logError(e) raise e except Exception as e: logger.logUnknownError("Annotation Storage Create Annotations", "", e) raise MongoDocumentException(0) else: raise StorageException(1)