class VedisBackend(DBPlugin): def connect(self): path = os.path.join(self.project.outdir, DB_NAME) self._db = Vedis(path) def get_sample(self, sha256): s = self._samples[sha256] j = json.loads(s) return Sample(self.project, j['file'], j['tags'], j['mutations'], j.get('base_sample', None)) def put_sample(self, sample): self._samples[sample.sha256] = sample.to_json() # keep reference of the sample for each tag :) for t in sample.tags: self.put_tag(t, sample.sha256) self._db.commit() def put_scan(self, scan, sample=None, sha256=None): if sha256: h = sha256 else: h = sample.sha256 self._scans[h] = json.dumps(scan) self._db.commit() def get_scan(self, sample=None, sha256=None): if sha256: h = sha256 else: h = sample.sha256 res = self._scans[h] if res: return json.loads(res) return None def put_tag(self, tag, sha256): t = self._db.Set('tag_' + tag) t.add(sha256) def get_tagged_samples(self, tag): return self._db.Set('tag_' + tag) @property def _samples(self): return self._db.Hash('samples') @property def _scans(self): return self._db.Hash('scans') @property def all_samples(self): # no way to use a generator with vedis # still ok for small analyses, we'll need to # support other DBs to reduce memory usage for s in self._samples.keys(): yield self.get_sample(s)
class VedisBackend(DBPlugin): def connect(self): path = os.path.join(self.project.outdir, DB_NAME) self._db = Vedis(path) def get_sample(self, sha256): s = self._samples[sha256] j = json.loads(s) bs = j.get('base_sample', None) if bs is not None: bs = self.get_sample(bs) #watch out for recursion! return Sample(self.project, j['file'], j['tags'], j['mutations'], bs) @commit_on_success def put_sample(self, sample): self._samples[sample.sha256] = sample.to_json() # keep reference of the sample for each tag :) for t in sample.tags: self.put_tag(t, sample.sha256) @commit_on_success def put_tag(self, tag, sha256): t = self._db.Set('tag_' + tag) t.add(sha256) def get_tagged_samples(self, tag): if isinstance(tag, basestring): tag = [ tag, ] for t in tag: for s in self._db.Set('tag_' + t): yield self.get_sample(s) @property def _samples(self): return self._db.Hash('samples') @property def _scans(self): return self._db.Hash('scans') def _pending_scans(self, scanner): return self._db.Set('{}_pending'.format(scanner)) def _done_scans(self, scanner): return self._db.Set('{}_done'.format(scanner)) def get_pending_scans(self, scanner): pending = self._pending_scans(scanner) if len(pending) == 0: return [] scans = [] for p in pending: d = self._get_scan(p) scans.append( Scan(scanner=scanner, uuid=d['uuid'], sample=d['sample'], scan_id=d['scan_id'], scan_results=d['scan_results'])) return scans @property def all_samples(self): # TODO: fix this for s in self._samples.keys(): yield self.get_sample(s) @commit_on_success def _put_scan_results(self, scan_result): self._scanresults[res.uuid] = scan_result # "update" the set of scanresults for a given scan @staticmethod def res_to_dict(scan): return { 'label': scan.label, 'sample': scan.sample.sha256, 'av': scan.av, 'extra': scan.extra } def _get_scan(self, uuid): return self._db.Hash(uuid) def _get_scan_result(self, scan): return self._db.Set(scan.uuid + '_results') def _res_by_sample(self, sample): return self._db.Set(scan.sample.sha + '_results') def _res_by_av(self, av): return self._db.Set(av + '_results') def _scan_by_sample(self, sample): return self._db.Set(sample.sha256 + '_scans') @commit_on_success def put_scan(self, scan): scanner = scan.scanner.short_name if scan.pending: # add to pending Set self._pending_scans(scanner).add(scan.uuid) else: self._pending_scans(scanner).remove(scan.uuid) self._put_scan_results(scan.scan_results) self._done_scan(scanner).add(scan.uuid) self._scan_by_sample(scan.sample).add(scan.uuid) for res in scan.scan_results: self._results(res.uuid).update(**res.to_dict()) # add its reference to sets for quick querying self._res_by_sample(scan.sample).add(res.uuid) self._res_by_av(res.av).add(res.uuid) self._get_scan(scan.uuid).update(**scan.to_dict()) l.debug("Scan %s stored in database", scan) def get_scan_results(self, av): pass def close(self): self._db.close()