def execute(self, args): """Remove specified elements.""" db = MessDB() cur = db.cursor() for row in args.inchikeys: inchikey = row.split()[0].strip() try: inchikey_dir = get_inchikey_dir(inchikey) shutil.rmtree(inchikey_dir) self.log_all.info('%s dir removed', inchikey) except OSError: self.log_console.info('%s did not have a directory', inchikey) try: parent = os.path.relpath(os.path.join(inchikey_dir, '../')) os.removedirs(parent) except OSError: pass records = 0 query = 'DELETE from molecule WHERE inchikey=?' cur.execute(query, (inchikey,)) records += cur.rowcount query = 'DELETE from molecule_synonym WHERE inchikey=?' cur.execute(query, (inchikey,)) records += cur.rowcount query = 'DELETE from molecule_source WHERE inchikey=?' cur.execute(query, (inchikey,)) records += cur.rowcount query = ('DELETE from molecule_state_method_property ' 'WHERE inchikey=?') cur.execute(query, (inchikey,)) records += cur.rowcount db.commit() self.log_all.info('%i %s records removed from db', records, inchikey)
def execute(self, args): """Run select query, output table.""" if args.inchikeys.name == '<stdin>' and args.inchikeys.isatty(): filter_from = None else: try: filter_from = set(row.split()[0].strip() for row in args.inchikeys) except IndexError: filter_from = set([]) return if args.query and (args.property_name or args.property_operator or args.property_value): sys.exit(('Custom SQL queries are mutually exclusive with ' 'property filtering.')) if (args.part or args.of) and not (args.part and args.of): sys.exit(('If you specify a --part n, you must also specify --of ' 'N (e.g. something like --part 1 --of 5).')) if args.part and args.of: if args.part > args.of: sys.exit('--part must be smaller than --of.') if args.part < 1: sys.exit('--part must be >=1.') alpha = string.ascii_uppercase alpha3 = [''.join([a, b, c]) for a in alpha for b in alpha for c in alpha] # AAA to ZZZ if args.of > len(alpha3): sys.exit(('MESS.DB does not support subsetting into more than ' '%i parts.' % len(alpha3))) subsets = [alpha3[i::args.of] for i in xrange(args.of)] subset = subsets[args.part - 1] db = MessDB() cur = db.cursor() if args.query: try: cur.execute(codecs.open(args.query, encoding='utf-8').read()) except sqlite3.OperationalError: sys.exit("'%s' does not contain valid sql." % args.query) except IOError: try: cur.execute(args.query) except sqlite3.OperationalError: sys.exit(("'%s' is neither valid sql nor a path " 'to a file containing valid sql.') % args.query) elif (args.property_name and args.property_operator and args.property_value is not None): query, values = self.property_query(args.property_name, args.property_operator, args.property_value, args.path) cur.execute(query, values) else: cur.execute('SELECT inchikey FROM molecule') # check that sql returns inchikey in first column if not cur.description[0][0].lower() == 'inchikey': sys.exit('Query must return inchikey in first column.') # print table writer = csv.writer(sys.stdout, delimiter=args.delimiter) if args.headers: writer.writerow(list(h[0] for h in cur.description)) for result in cur: if filter_from is not None and result[0] not in filter_from: continue if args.regex_subset and not re.match(args.regex_subset, result[0], re.IGNORECASE): continue if args.part and args.of: if not any(result[0].startswith(a) for a in subset): continue if args.smarts: matches = 0 query = 'SELECT inchi FROM molecule WHERE inchikey = ?' inchi = db.execute(query, (result[0],)).fetchone()[0] mol = pybel.readstring('inchi', 'InChI=%s' % inchi) for (smarts_obj, smarts_str) in Match.smarts_generator(args.smarts): matches += len(smarts_obj.findall(mol)) if not matches: continue writer.writerow(list(xstr(v).decode('utf-8') for v in result)) db.close() # must be closed manually to prevent db locking during pipe