From 5cfb8b1e17796056521b17143037a396f8f23beb Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Sat, 23 Apr 2016 17:00:11 -0400 Subject: [PATCH] Postgresql and Mysql limit/offset --- gramps/plugins/database/dbapi.py | 2 +- .../plugins/database/dbapi_support/mysql.py | 11 +++++-- .../database/dbapi_support/postgresql.py | 32 +++++++++++++------ 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/gramps/plugins/database/dbapi.py b/gramps/plugins/database/dbapi.py index c9e5ac862..da337fe40 100644 --- a/gramps/plugins/database/dbapi.py +++ b/gramps/plugins/database/dbapi.py @@ -1859,7 +1859,7 @@ class DBAPI(DbGeneric): if get_count_only: select_fields = ["1"] if start: - query = "SELECT %s FROM %s %s %s LIMIT %s, %s" % ( + query = "SELECT %s FROM %s %s %s LIMIT %s, %s " % ( ", ".join(select_fields), table_name, where_clause, order_clause, start, limit ) else: diff --git a/gramps/plugins/database/dbapi_support/mysql.py b/gramps/plugins/database/dbapi_support/mysql.py index 555fa54c5..cc92024e0 100644 --- a/gramps/plugins/database/dbapi_support/mysql.py +++ b/gramps/plugins/database/dbapi_support/mysql.py @@ -1,4 +1,5 @@ import MySQLdb +import re MySQLdb.paramstyle = 'qmark' ## Doesn't work @@ -36,8 +37,14 @@ class MySQL(object): ## LIMIT offset, -1 query = query.replace("LIMIT -1", "LIMIT 18446744073709551615") ## - ## FIXME: regex match: - #query = query.replace("LIMIT .*,-1", "LIMIT $1, ALL") + match = re.match(".* LIMIT (.*), (.*) ", query) + if match and match.groups(): + offset, count = match.groups() + if count == "-1": + count = "18446744073709551615" + query = re.sub("(.*) LIMIT (.*), (.*) ", + "\\1 LIMIT %s, %s " % (offset, count), + query) return query def execute(self, query, args=[]): diff --git a/gramps/plugins/database/dbapi_support/postgresql.py b/gramps/plugins/database/dbapi_support/postgresql.py index 1a5a05e4b..25f3415ed 100644 --- a/gramps/plugins/database/dbapi_support/postgresql.py +++ b/gramps/plugins/database/dbapi_support/postgresql.py @@ -1,4 +1,5 @@ import psycopg2 +import re psycopg2.paramstyle = 'format' @@ -23,13 +24,28 @@ class Postgresql(object): self.connection.autocommit = True self.cursor = self.connection.cursor() + def _hack_query(self, query): + query = query.replace("?", "%s") + query = query.replace("REGEXP", "~") + query = query.replace("desc", "desc_") + ## LIMIT offset, count + ## count can be -1, for all + ## LIMIT -1 + ## LIMIT offset, -1 + query = query.replace("LIMIT -1", + "LIMIT all") ## + match = re.match(".* LIMIT (.*), (.*) ", query) + if match and match.groups(): + offset, count = match.groups() + if count == "-1": + count = "all" + query = re.sub("(.*) LIMIT (.*), (.*) ", + "\\1 LIMIT %s OFFSET %s " % (count, offset), + query) + return query + def execute(self, *args, **kwargs): - sql = args[0] - sql = sql.replace("?", "%s") - sql = sql.replace("REGEXP", "~") - sql = sql.replace("desc", "desc_") - sql = sql.replace("LIMIT -1", "LIMIT all") - ## FIXME: limit offset, -1 + sql = self._hack_query(args[0]) if len(args) > 1: args = args[1] else: @@ -56,10 +72,8 @@ class Postgresql(object): self.connection.rollback() def try_execute(self, sql): - sql = sql.replace("?", "%s") + sql = self._hack_query(sql) sql = sql.replace("BLOB", "bytea") - sql = sql.replace("desc", "desc_") - sql = sql.replace("LIMIT -1", "LIMIT all") try: self.cursor.execute(sql) except Exception as exc: