Esempio n. 1
0
 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
Esempio n. 2
0
 def test_xstr(self):
     self.assertEqual(utils.xstr('string'), 'string')
     self.assertEqual(utils.xstr(None), '')