Spaces:
No application file
No application file
| # Copyright 2002 by Andrew Dalke. All rights reserved. | |
| # Revisions 2007-2010 copyright by Peter Cock. All rights reserved. | |
| # Revisions 2009 copyright by Brad Chapman. All rights reserved. | |
| # Revisions 2013 copyright by Tiago Antao. All rights reserved. | |
| # | |
| # This file is part of the Biopython distribution and governed by your | |
| # choice of the "Biopython License Agreement" or the "BSD 3-Clause License". | |
| # Please see the LICENSE file that should have been included as part of this | |
| # package. | |
| # | |
| # Note that BioSQL (including the database schema and scripts) is | |
| # available and licensed separately. Please consult www.biosql.org | |
| """Helper code for Biopython's BioSQL code (for internal use).""" | |
| import os | |
| _dbutils = {} | |
| class Generic_dbutils: | |
| """Default database utilities.""" | |
| def __init__(self): | |
| """Create a Generic_dbutils object.""" | |
| pass | |
| def tname(self, table): | |
| """Return the name of the table.""" | |
| if table != "biosequence": | |
| return table | |
| else: | |
| return "bioentry" | |
| def last_id(self, cursor, table): | |
| """Return the last used id for a table.""" | |
| # XXX: Unsafe without transactions isolation | |
| table = self.tname(table) | |
| sql = f"select max({table}_id) from {table}" | |
| cursor.execute(sql) | |
| rv = cursor.fetchone() | |
| return rv[0] | |
| def execute(self, cursor, sql, args=None): | |
| """Just execute an sql command.""" | |
| cursor.execute(sql, args or ()) | |
| def executemany(self, cursor, sql, seq): | |
| """Execute many sql commands.""" | |
| cursor.executemany(sql, seq) | |
| def autocommit(self, conn, y=1): | |
| """Set autocommit on the database connection.""" | |
| # Let's hope it was not really needed | |
| pass | |
| class Sqlite_dbutils(Generic_dbutils): | |
| """Custom database utilities for SQLite.""" | |
| def _sub_placeholder(self, sql): | |
| """Format the argument placeholders for sqlite (PRIVATE).""" | |
| return sql.replace("%s", "?") | |
| def execute(self, cursor, sql, args=None): | |
| """Execute SQL command. | |
| Replaces %s with ? for variable substitution in sqlite3. | |
| """ | |
| sql = self._sub_placeholder(sql) | |
| cursor.execute(sql, args or ()) | |
| def executemany(self, cursor, sql, seq): | |
| """Execute many sql statements.""" | |
| sql = self._sub_placeholder(sql) | |
| cursor.executemany(sql, seq) | |
| _dbutils["sqlite3"] = Sqlite_dbutils | |
| class Mysql_dbutils(Generic_dbutils): | |
| """Custom database utilities for MySQL.""" | |
| def last_id(self, cursor, table): | |
| """Return the last used id for a table.""" | |
| if os.name == "java": | |
| return Generic_dbutils.last_id(self, cursor, table) | |
| try: | |
| # This worked on older versions of MySQL | |
| return cursor.insert_id() | |
| except AttributeError: | |
| # See bug 2390 | |
| # Google suggests this is the new way, | |
| # same fix also suggested by Eric Gibert: | |
| return cursor.lastrowid | |
| _dbutils["MySQLdb"] = Mysql_dbutils | |
| class _PostgreSQL_dbutils(Generic_dbutils): | |
| """Base class for any PostgreSQL adaptor.""" | |
| def next_id(self, cursor, table): | |
| table = self.tname(table) | |
| sql = f"SELECT nextval('{table}_pk_seq')" | |
| cursor.execute(sql) | |
| rv = cursor.fetchone() | |
| return rv[0] | |
| def last_id(self, cursor, table): | |
| table = self.tname(table) | |
| sql = f"SELECT currval('{table}_pk_seq')" | |
| cursor.execute(sql) | |
| rv = cursor.fetchone() | |
| return rv[0] | |
| class Psycopg2_dbutils(_PostgreSQL_dbutils): | |
| """Custom database utilities for Psycopg2 (PostgreSQL).""" | |
| def autocommit(self, conn, y=True): | |
| """Set autocommit on the database connection.""" | |
| if y: | |
| if os.name == "java": | |
| conn.autocommit = 1 | |
| else: | |
| conn.set_isolation_level(0) | |
| else: | |
| if os.name == "java": | |
| conn.autocommit = 0 | |
| else: | |
| conn.set_isolation_level(1) | |
| _dbutils["psycopg2"] = Psycopg2_dbutils | |
| class Pgdb_dbutils(_PostgreSQL_dbutils): | |
| """Custom database utilities for Pgdb (aka PyGreSQL, for PostgreSQL).""" | |
| def autocommit(self, conn, y=True): | |
| """Set autocommit on the database connection. Currently not implemented.""" | |
| raise NotImplementedError("pgdb does not support this!") | |
| _dbutils["pgdb"] = Pgdb_dbutils | |
| def get_dbutils(module_name): | |
| """Return the correct dbutils object for the database driver.""" | |
| try: | |
| return _dbutils[module_name]() | |
| except KeyError: | |
| return Generic_dbutils() | |