9748: Use COLLATE clause rather than locale specific columns
This commit is contained in:
parent
b556b29b25
commit
27c2b0c81d
@ -2517,21 +2517,6 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
|||||||
order_by = " ".join(order_by_list)
|
order_by = " ".join(order_by_list)
|
||||||
return glocale.sort_key(order_by)
|
return glocale.sort_key(order_by)
|
||||||
|
|
||||||
def _order_by_place_key(self, place):
|
|
||||||
return glocale.sort_key(str(int(place.place_type)) + ", " + place.name.value)
|
|
||||||
|
|
||||||
def _order_by_source_key(self, source):
|
|
||||||
return glocale.sort_key(source.title)
|
|
||||||
|
|
||||||
def _order_by_citation_key(self, citation):
|
|
||||||
return glocale.sort_key(citation.page)
|
|
||||||
|
|
||||||
def _order_by_media_key(self, media):
|
|
||||||
return glocale.sort_key(media.desc)
|
|
||||||
|
|
||||||
def _order_by_tag_key(self, key):
|
|
||||||
return glocale.sort_key(key)
|
|
||||||
|
|
||||||
def _get_person_data(self, person):
|
def _get_person_data(self, person):
|
||||||
"""
|
"""
|
||||||
Given a Person, return primary_name.first_name and surname.
|
Given a Person, return primary_name.first_name and surname.
|
||||||
|
@ -184,7 +184,6 @@ class DBAPI(DbGeneric):
|
|||||||
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
||||||
'given_name TEXT, '
|
'given_name TEXT, '
|
||||||
'surname TEXT, '
|
'surname TEXT, '
|
||||||
'order_by TEXT, '
|
|
||||||
'gramps_id TEXT, '
|
'gramps_id TEXT, '
|
||||||
'blob_data BLOB'
|
'blob_data BLOB'
|
||||||
')')
|
')')
|
||||||
@ -199,14 +198,12 @@ class DBAPI(DbGeneric):
|
|||||||
self.dbapi.execute('CREATE TABLE source '
|
self.dbapi.execute('CREATE TABLE source '
|
||||||
'('
|
'('
|
||||||
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
||||||
'order_by TEXT, '
|
|
||||||
'gramps_id TEXT, '
|
'gramps_id TEXT, '
|
||||||
'blob_data BLOB'
|
'blob_data BLOB'
|
||||||
')')
|
')')
|
||||||
self.dbapi.execute('CREATE TABLE citation '
|
self.dbapi.execute('CREATE TABLE citation '
|
||||||
'('
|
'('
|
||||||
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
||||||
'order_by TEXT, '
|
|
||||||
'gramps_id TEXT, '
|
'gramps_id TEXT, '
|
||||||
'blob_data BLOB'
|
'blob_data BLOB'
|
||||||
')')
|
')')
|
||||||
@ -219,7 +216,6 @@ class DBAPI(DbGeneric):
|
|||||||
self.dbapi.execute('CREATE TABLE media '
|
self.dbapi.execute('CREATE TABLE media '
|
||||||
'('
|
'('
|
||||||
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
||||||
'order_by TEXT, '
|
|
||||||
'gramps_id TEXT, '
|
'gramps_id TEXT, '
|
||||||
'blob_data BLOB'
|
'blob_data BLOB'
|
||||||
')')
|
')')
|
||||||
@ -227,7 +223,6 @@ class DBAPI(DbGeneric):
|
|||||||
'('
|
'('
|
||||||
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
||||||
'enclosed_by VARCHAR(50), '
|
'enclosed_by VARCHAR(50), '
|
||||||
'order_by TEXT, '
|
|
||||||
'gramps_id TEXT, '
|
'gramps_id TEXT, '
|
||||||
'blob_data BLOB'
|
'blob_data BLOB'
|
||||||
')')
|
')')
|
||||||
@ -246,7 +241,6 @@ class DBAPI(DbGeneric):
|
|||||||
self.dbapi.execute('CREATE TABLE tag '
|
self.dbapi.execute('CREATE TABLE tag '
|
||||||
'('
|
'('
|
||||||
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
'handle VARCHAR(50) PRIMARY KEY NOT NULL, '
|
||||||
'order_by TEXT, '
|
|
||||||
'blob_data BLOB'
|
'blob_data BLOB'
|
||||||
')')
|
')')
|
||||||
# Secondary:
|
# Secondary:
|
||||||
@ -274,35 +268,36 @@ class DBAPI(DbGeneric):
|
|||||||
'male INTEGER, '
|
'male INTEGER, '
|
||||||
'unknown INTEGER'
|
'unknown INTEGER'
|
||||||
')')
|
')')
|
||||||
|
|
||||||
|
self.rebuild_secondary_fields()
|
||||||
|
|
||||||
## Indices:
|
## Indices:
|
||||||
self.dbapi.execute('CREATE INDEX person_order_by '
|
|
||||||
'ON person(order_by)')
|
|
||||||
self.dbapi.execute('CREATE INDEX person_gramps_id '
|
self.dbapi.execute('CREATE INDEX person_gramps_id '
|
||||||
'ON person(gramps_id)')
|
'ON person(gramps_id)')
|
||||||
self.dbapi.execute('CREATE INDEX person_surname '
|
self.dbapi.execute('CREATE INDEX person_surname '
|
||||||
'ON person(surname)')
|
'ON person(surname)')
|
||||||
self.dbapi.execute('CREATE INDEX person_given_name '
|
self.dbapi.execute('CREATE INDEX person_given_name '
|
||||||
'ON person(given_name)')
|
'ON person(given_name)')
|
||||||
self.dbapi.execute('CREATE INDEX source_order_by '
|
self.dbapi.execute('CREATE INDEX source_title '
|
||||||
'ON source(order_by)')
|
'ON source(title)')
|
||||||
self.dbapi.execute('CREATE INDEX source_gramps_id '
|
self.dbapi.execute('CREATE INDEX source_gramps_id '
|
||||||
'ON source(gramps_id)')
|
'ON source(gramps_id)')
|
||||||
self.dbapi.execute('CREATE INDEX citation_order_by '
|
self.dbapi.execute('CREATE INDEX citation_page '
|
||||||
'ON citation(order_by)')
|
'ON citation(page)')
|
||||||
self.dbapi.execute('CREATE INDEX citation_gramps_id '
|
self.dbapi.execute('CREATE INDEX citation_gramps_id '
|
||||||
'ON citation(gramps_id)')
|
'ON citation(gramps_id)')
|
||||||
self.dbapi.execute('CREATE INDEX media_order_by '
|
self.dbapi.execute('CREATE INDEX media_desc '
|
||||||
'ON media(order_by)')
|
'ON media(desc)')
|
||||||
self.dbapi.execute('CREATE INDEX media_gramps_id '
|
self.dbapi.execute('CREATE INDEX media_gramps_id '
|
||||||
'ON media(gramps_id)')
|
'ON media(gramps_id)')
|
||||||
self.dbapi.execute('CREATE INDEX place_order_by '
|
self.dbapi.execute('CREATE INDEX place_title '
|
||||||
'ON place(order_by)')
|
'ON place(title)')
|
||||||
self.dbapi.execute('CREATE INDEX place_enclosed_by '
|
self.dbapi.execute('CREATE INDEX place_enclosed_by '
|
||||||
'ON place(enclosed_by)')
|
'ON place(enclosed_by)')
|
||||||
self.dbapi.execute('CREATE INDEX place_gramps_id '
|
self.dbapi.execute('CREATE INDEX place_gramps_id '
|
||||||
'ON place(gramps_id)')
|
'ON place(gramps_id)')
|
||||||
self.dbapi.execute('CREATE INDEX tag_order_by '
|
self.dbapi.execute('CREATE INDEX tag_name '
|
||||||
'ON tag(order_by)')
|
'ON tag(name)')
|
||||||
self.dbapi.execute('CREATE INDEX reference_ref_handle '
|
self.dbapi.execute('CREATE INDEX reference_ref_handle '
|
||||||
'ON reference(ref_handle)')
|
'ON reference(ref_handle)')
|
||||||
self.dbapi.execute('CREATE INDEX family_gramps_id '
|
self.dbapi.execute('CREATE INDEX family_gramps_id '
|
||||||
@ -316,7 +311,6 @@ class DBAPI(DbGeneric):
|
|||||||
self.dbapi.execute('CREATE INDEX reference_obj_handle '
|
self.dbapi.execute('CREATE INDEX reference_obj_handle '
|
||||||
'ON reference(obj_handle)')
|
'ON reference(obj_handle)')
|
||||||
|
|
||||||
self.rebuild_secondary_fields()
|
|
||||||
|
|
||||||
def close_backend(self):
|
def close_backend(self):
|
||||||
self.dbapi.close()
|
self.dbapi.close()
|
||||||
@ -470,7 +464,8 @@ class DBAPI(DbGeneric):
|
|||||||
If sort_handles is True, the list is sorted by surnames.
|
If sort_handles is True, the list is sorted by surnames.
|
||||||
"""
|
"""
|
||||||
if sort_handles:
|
if sort_handles:
|
||||||
self.dbapi.execute("SELECT handle FROM person ORDER BY order_by")
|
self.dbapi.execute("SELECT handle FROM person "
|
||||||
|
"ORDER BY surname COLLATE glocale")
|
||||||
else:
|
else:
|
||||||
self.dbapi.execute("SELECT handle FROM person")
|
self.dbapi.execute("SELECT handle FROM person")
|
||||||
rows = self.dbapi.fetchall()
|
rows = self.dbapi.fetchall()
|
||||||
@ -484,21 +479,22 @@ class DBAPI(DbGeneric):
|
|||||||
If sort_handles is True, the list is sorted by surnames.
|
If sort_handles is True, the list is sorted by surnames.
|
||||||
"""
|
"""
|
||||||
if sort_handles:
|
if sort_handles:
|
||||||
self.dbapi.execute("""SELECT f.handle FROM
|
sql = ("SELECT family.handle " +
|
||||||
(SELECT family.*
|
"FROM family " +
|
||||||
FROM family LEFT JOIN
|
"LEFT JOIN person AS father " +
|
||||||
person AS father
|
"ON family.father_handle = father.handle " +
|
||||||
ON family.father_handle = father.handle LEFT JOIN
|
"LEFT JOIN person AS mother " +
|
||||||
person AS mother
|
"ON family.mother_handle = mother.handle " +
|
||||||
on family.mother_handle = mother.handle
|
"ORDER BY (CASE WHEN father.handle IS NULL " +
|
||||||
order by (case when father.handle is null
|
"THEN mother.surname " +
|
||||||
then mother.surname
|
"ELSE father.surname " +
|
||||||
else father.surname
|
"END), " +
|
||||||
end),
|
"(CASE WHEN family.handle IS NULL " +
|
||||||
(case when family.handle is null
|
"THEN mother.given_name " +
|
||||||
then mother.given_name
|
"ELSE father.given_name " +
|
||||||
else father.given_name
|
"END) " +
|
||||||
end)) AS f""")
|
"COLLATE glocale")
|
||||||
|
self.dbapi.execute(sql)
|
||||||
else:
|
else:
|
||||||
self.dbapi.execute("SELECT handle FROM family")
|
self.dbapi.execute("SELECT handle FROM family")
|
||||||
rows = self.dbapi.fetchall()
|
rows = self.dbapi.fetchall()
|
||||||
@ -521,7 +517,8 @@ class DBAPI(DbGeneric):
|
|||||||
If sort_handles is True, the list is sorted by Citation title.
|
If sort_handles is True, the list is sorted by Citation title.
|
||||||
"""
|
"""
|
||||||
if sort_handles:
|
if sort_handles:
|
||||||
self.dbapi.execute("SELECT handle FROM citation ORDER BY order_by")
|
self.dbapi.execute("SELECT handle FROM citation "
|
||||||
|
"ORDER BY page COLLATE glocale")
|
||||||
else:
|
else:
|
||||||
self.dbapi.execute("SELECT handle FROM citation")
|
self.dbapi.execute("SELECT handle FROM citation")
|
||||||
rows = self.dbapi.fetchall()
|
rows = self.dbapi.fetchall()
|
||||||
@ -535,7 +532,8 @@ class DBAPI(DbGeneric):
|
|||||||
If sort_handles is True, the list is sorted by Source title.
|
If sort_handles is True, the list is sorted by Source title.
|
||||||
"""
|
"""
|
||||||
if sort_handles:
|
if sort_handles:
|
||||||
self.dbapi.execute("SELECT handle FROM source ORDER BY order_by")
|
self.dbapi.execute("SELECT handle FROM source "
|
||||||
|
"ORDER BY title COLLATE glocale")
|
||||||
else:
|
else:
|
||||||
self.dbapi.execute("SELECT handle from source")
|
self.dbapi.execute("SELECT handle from source")
|
||||||
rows = self.dbapi.fetchall()
|
rows = self.dbapi.fetchall()
|
||||||
@ -549,7 +547,8 @@ class DBAPI(DbGeneric):
|
|||||||
If sort_handles is True, the list is sorted by Place title.
|
If sort_handles is True, the list is sorted by Place title.
|
||||||
"""
|
"""
|
||||||
if sort_handles:
|
if sort_handles:
|
||||||
self.dbapi.execute("SELECT handle FROM place ORDER BY order_by")
|
self.dbapi.execute("SELECT handle FROM place "
|
||||||
|
"ORDER BY title COLLATE glocale")
|
||||||
else:
|
else:
|
||||||
self.dbapi.execute("SELECT handle FROM place")
|
self.dbapi.execute("SELECT handle FROM place")
|
||||||
rows = self.dbapi.fetchall()
|
rows = self.dbapi.fetchall()
|
||||||
@ -572,7 +571,8 @@ class DBAPI(DbGeneric):
|
|||||||
If sort_handles is True, the list is sorted by title.
|
If sort_handles is True, the list is sorted by title.
|
||||||
"""
|
"""
|
||||||
if sort_handles:
|
if sort_handles:
|
||||||
self.dbapi.execute("SELECT handle FROM media ORDER BY order_by")
|
self.dbapi.execute("SELECT handle FROM media "
|
||||||
|
"ORDER BY desc COLLATE glocale")
|
||||||
else:
|
else:
|
||||||
self.dbapi.execute("SELECT handle FROM media")
|
self.dbapi.execute("SELECT handle FROM media")
|
||||||
rows = self.dbapi.fetchall()
|
rows = self.dbapi.fetchall()
|
||||||
@ -595,7 +595,8 @@ class DBAPI(DbGeneric):
|
|||||||
If sort_handles is True, the list is sorted by Tag name.
|
If sort_handles is True, the list is sorted by Tag name.
|
||||||
"""
|
"""
|
||||||
if sort_handles:
|
if sort_handles:
|
||||||
self.dbapi.execute("SELECT handle FROM tag ORDER BY order_by")
|
self.dbapi.execute("SELECT handle FROM tag "
|
||||||
|
"ORDER BY name COLLATE glocale")
|
||||||
else:
|
else:
|
||||||
self.dbapi.execute("SELECT handle FROM tag")
|
self.dbapi.execute("SELECT handle FROM tag")
|
||||||
rows = self.dbapi.fetchall()
|
rows = self.dbapi.fetchall()
|
||||||
@ -1092,26 +1093,10 @@ class DBAPI(DbGeneric):
|
|||||||
values.append(given_name)
|
values.append(given_name)
|
||||||
sets.append("surname = ?")
|
sets.append("surname = ?")
|
||||||
values.append(surname)
|
values.append(surname)
|
||||||
sets.append("order_by = ?")
|
|
||||||
values.append(self._order_by_person_key(obj))
|
|
||||||
if table == 'Place':
|
if table == 'Place':
|
||||||
handle = self._get_place_data(obj)
|
handle = self._get_place_data(obj)
|
||||||
sets.append("enclosed_by = ?")
|
sets.append("enclosed_by = ?")
|
||||||
values.append(handle)
|
values.append(handle)
|
||||||
sets.append("order_by = ?")
|
|
||||||
values.append(self._order_by_place_key(obj))
|
|
||||||
if table == 'Source':
|
|
||||||
sets.append("order_by = ?")
|
|
||||||
values.append(self._order_by_source_key(obj))
|
|
||||||
if table == 'Citation':
|
|
||||||
sets.append("order_by = ?")
|
|
||||||
values.append(self._order_by_citation_key(obj))
|
|
||||||
if table == 'Media':
|
|
||||||
sets.append("order_by = ?")
|
|
||||||
values.append(self._order_by_media_key(obj))
|
|
||||||
if table == 'Tag':
|
|
||||||
sets.append("order_by = ?")
|
|
||||||
values.append(self._order_by_tag_key(obj.name))
|
|
||||||
|
|
||||||
if len(values) > 0:
|
if len(values) > 0:
|
||||||
table_name = table.lower()
|
table_name = table.lower()
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
import psycopg2
|
import psycopg2
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -56,6 +57,9 @@ class Postgresql:
|
|||||||
self.__connection = psycopg2.connect(*args, **kwargs)
|
self.__connection = psycopg2.connect(*args, **kwargs)
|
||||||
self.__connection.autocommit = True
|
self.__connection.autocommit = True
|
||||||
self.__cursor = self.__connection.cursor()
|
self.__cursor = self.__connection.cursor()
|
||||||
|
locale = os.environ.get('LANG', 'en_US.utf8')
|
||||||
|
self.execute("DROP COLLTAION IF EXISTS glocale")
|
||||||
|
self.execute("CREATE COLLATION glocale (LOCALE = '%s')" % locale)
|
||||||
|
|
||||||
def _hack_query(self, query):
|
def _hack_query(self, query):
|
||||||
query = query.replace("?", "%s")
|
query = query.replace("?", "%s")
|
||||||
|
@ -38,6 +38,7 @@ import re
|
|||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
from gramps.gen.db.dbconst import ARRAYSIZE
|
from gramps.gen.db.dbconst import ARRAYSIZE
|
||||||
|
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||||
|
|
||||||
sqlite3.paramstyle = 'qmark'
|
sqlite3.paramstyle = 'qmark'
|
||||||
|
|
||||||
@ -82,6 +83,7 @@ class Sqlite:
|
|||||||
self.log = logging.getLogger(".sqlite")
|
self.log = logging.getLogger(".sqlite")
|
||||||
self.__connection = sqlite3.connect(*args, **kwargs)
|
self.__connection = sqlite3.connect(*args, **kwargs)
|
||||||
self.__cursor = self.__connection.cursor()
|
self.__cursor = self.__connection.cursor()
|
||||||
|
self.__connection.create_collation("glocale", glocale.strcoll)
|
||||||
self.__connection.create_function("regexp", 2, regexp)
|
self.__connection.create_function("regexp", 2, regexp)
|
||||||
|
|
||||||
def execute(self, *args, **kwargs):
|
def execute(self, *args, **kwargs):
|
||||||
|
@ -216,6 +216,12 @@ class DbRandomTest(unittest.TestCase):
|
|||||||
self.db.get_number_of_families,
|
self.db.get_number_of_families,
|
||||||
sort_handles=True)
|
sort_handles=True)
|
||||||
|
|
||||||
|
def test_get_place_handles_sort(self):
|
||||||
|
self.__get_handles_test('Place',
|
||||||
|
self.db.get_place_handles,
|
||||||
|
self.db.get_number_of_places,
|
||||||
|
sort_handles=True)
|
||||||
|
|
||||||
def test_get_source_handles_sort(self):
|
def test_get_source_handles_sort(self):
|
||||||
self.__get_handles_test('Source',
|
self.__get_handles_test('Source',
|
||||||
self.db.get_source_handles,
|
self.db.get_source_handles,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user