def query(self, module, statement, args=(), forceNoCache=False, commit=False): """ execute a query on the database. be sure to deliver the module. it is necessary to determine tablenames """ try: mutex = self._core.get_configuration().get_entry( "core.webpath") + "/db.mutex" if commit: #only if writing stuff while os.path.exists(mutex): time.sleep(0.000001) os.mkdir(mutex) if self._connection is None: raise DatabaseException(DatabaseException.get_msg(2)) if module.get_name() != "de.masterprogs.skarphed.core": statement = self._replace_module_tables(module, statement) cur = self._connection.cursor() try: prepared, cur = self._queryCache(cur, statement) cur.execute(prepared, args) except fdb.fbcore.DatabaseError, e: raise DatabaseException(str(e)) if commit: self.commit() return cur
def _replace_module_tables(self, module, query): """ replaces module-based tablenames like 'de.grinhold.skarphed.news.news' with an actual SQL-table like 'TAB_000004' """ tagpattern = re.compile('\$\{[A-Za-z0-9.]+\}') matches = tagpattern.findall(query) matches = list(set(matches)) # making matches unique matches = map(lambda s: s[2:-1], matches) matchesRaw = list(matches) modules = [module.get_name()] for match in matches: splitted = match.split(".") if len(splitted) > 1: matches.append(splitted[-1]) matches.remove(match) splitted.remove(splitted[-1]) modules.append(".".join(splitted)) tableQuery = """SELECT MDT_ID, MDT_NAME, MOD_NAME FROM MODULETABLES INNER JOIN MODULES ON (MDT_MOD_ID = MOD_ID ) WHERE MOD_NAME IN (%s) AND MDT_NAME IN (%s) ;""" % ( "'" + "','".join(modules) + "'", "'" + "','".join(matches) + "'") cur = self._connection.cursor() cur.execute(tableQuery) replacementsDone = [] for res in cur.fetchallmap(): pattern = "${" + res["MOD_NAME"] + "." + res["MDT_NAME"] + "}" tableId = str(res["MDT_ID"]) tableId = "TAB_" + "0" * (6 - len(tableId)) + tableId query = query.replace(pattern, tableId) replacementsDone.append(res["MOD_NAME"] + "." + res["MDT_NAME"]) if res["MOD_NAME"] == module.get_name(): query = query.replace("${" + res["MDT_NAME"] + "}", tableId) if len(matchesRaw) != len(replacementsDone): for replacement in replacementsDone: matchesRaw.remove(replacement) raise DatabaseException( DatabaseException.get_msg(3, str(matchesRaw))) return query
def query(self, statement, args=(), module=None, forceNoCache=False, commit=False): """ execute a query on the database. be sure to deliver the module. it is necessary to determine tablenames """ try: mutex = Configuration().get_entry("core.webpath")+"/db.mutex" if commit: #only if writing stuff while os.path.exists(mutex): time.sleep(0.000001) os.mkdir(mutex) if self._connection is None: raise DatabaseException(DatabaseException.get_msg(2)) if module is not None: statement = self._replace_module_tables(module,statement) cur = self._connection.cursor() try: prepared, cur = self._queryCache(cur, statement) cur.execute(prepared,args) except fdb.fbcore.DatabaseError,e: raise DatabaseException(str(e)) if commit: self.commit() return cur
def connect(self): """ The class actually connects to the database and stores the connection in _connection """ if None in (self._user, self._ip, self._dbname, self._password): raise DatabaseException(DatabaseException.get_msg(1)) #TODO: Globally Definable DB-Path try: self._connection = fdb.connect( host=self._ip, database='/var/lib/firebird/2.5/data/' + self._dbname, user=self._user, password=self._password) except fdb.fbcore.DatabaseError, e: raise DatabaseException(e.args[0])
def _replace_module_tables(self, module, query): """ replaces module-based tablenames like 'de.grinhold.skarphed.news.news' with an actual SQL-table like 'TAB_000004' """ tagpattern = re.compile('\$\{[A-Za-z0-9.]+\}') matches = tagpattern.findall(query) matches = list(set(matches)) # making matches unique matches = map(lambda s: s[2:-1], matches) matchesRaw = list(matches) modules = [module.get_name()] for match in matches: splitted = match.split(".") if len(splitted) > 1: matches.append(splitted[-1]) matches.remove(match) splitted.remove(splitted[-1]) modules.append(".".join(splitted)) tableQuery = """SELECT MDT_ID, MDT_NAME, MOD_NAME FROM MODULETABLES INNER JOIN MODULES ON (MDT_MOD_ID = MOD_ID ) WHERE MOD_NAME IN (%s) AND MDT_NAME IN (%s) ;"""%("'"+"','".join(modules)+"'","'"+"','".join(matches)+"'") cur = self._connection.cursor() cur.execute(tableQuery) replacementsDone = [] for res in cur.fetchallmap(): pattern = "${"+res["MOD_NAME"]+"."+res["MDT_NAME"]+"}" tableId = str(res["MDT_ID"]) tableId = "TAB_"+"0"*(6-len(tableId))+tableId query = query.replace(pattern, tableId) replacementsDone.append(res["MOD_NAME"]+"."+res["MDT_NAME"]) if res["MOD_NAME"] == module.get_name(): query = query.replace("${"+res["MDT_NAME"]+"}", tableId) if len(matchesRaw) != len(replacementsDone): for replacement in replacementsDone: matchesRaw.remove(replacement) raise DatabaseException(DatabaseException.get_msg(3,str(matchesRaw))) return query
def connect(self): """ The class actually connects to the database and stores the connection in _connection """ if None in (self._user, self._ip, self._dbname, self._password): raise DatabaseException(DatabaseException.get_msg(1)) #TODO: Globally Definable DB-Path try: self._connection = fdb.connect( host=self._ip, database='/var/lib/firebird/2.5/data/'+self._dbname, user=self._user, password=self._password, charset="UTF8") except fdb.fbcore.DatabaseError, e: raise DatabaseException(e.args[0])