class FormDocumentStore(DocumentStore): def __init__(self, domain, xmlns=None): self.domain = domain self.form_accessors = FormAccessors(domain=domain) self.xmlns = xmlns def get_document(self, doc_id): try: form = self.form_accessors.get_form(doc_id) return self._to_json(form) except (XFormNotFound, BlobError) as e: raise DocumentNotFoundError(e) @staticmethod def _to_json(form): if isinstance(form, XFormInstanceSQL): return form.to_json(include_attachments=True) else: return form.to_json() def iter_document_ids(self): return iter(self.form_accessors.iter_form_ids_by_xmlns(self.xmlns)) def iter_documents(self, ids): for wrapped_form in self.form_accessors.iter_forms(ids): try: yield self._to_json(wrapped_form) except (DocumentNotFoundError, MissingFormXml): pass
def handle(self, domain, xmlns, app_id, dry_run, xform_ids, **options): accessor = FormAccessors(domain) if xform_ids: form_ids = xform_ids.split(',') else: form_ids = accessor.iter_form_ids_by_xmlns(xmlns) attachments_to_delete = [] for form_id in form_ids: form = accessor.get_with_attachments(form_id) if form.domain != domain or form.xmlns != xmlns or form.app_id != app_id: continue print( f'{form_id}\t{",".join(form.attachments) or "No attachments to delete"}' ) for name, blob_meta in form.attachments.items(): attachments_to_delete.append((form_id, name, blob_meta)) if not dry_run: if input("Delete all the above attachments? [y/n]").lower() in ( 'y', 'yes'): for form_id, name, blob_meta in attachments_to_delete: print(f'Deleting {form_id}/{name} ({blob_meta.key})') # todo: if this is ever too slow, we can bulk delete instead # https://github.com/dimagi/commcare-hq/pull/26672#discussion_r380522955 get_blob_db().delete(blob_meta.key)
class ReadonlyFormDocumentStore(ReadOnlyDocumentStore): def __init__(self, domain, xmlns=None): self.domain = domain self.form_accessors = FormAccessors(domain=domain) self.xmlns = xmlns def get_document(self, doc_id): try: form = self.form_accessors.get_form(doc_id) if isinstance(form, XFormInstanceSQL): return form.to_json(include_attachments=True) else: return form.to_json() except (XFormNotFound, BlobError) as e: raise DocumentNotFoundError(e) def iter_document_ids(self, last_id=None): # todo: support last_id return iter(self.form_accessors.iter_form_ids_by_xmlns(self.xmlns)) def iter_documents(self, ids): for wrapped_form in self.form_accessors.iter_forms(ids): yield wrapped_form.to_json()