Allow multiple collations per connection
This fixes collation for translated reports and multi-user access for PostgreSQL.
This commit is contained in:
parent
95d84573d4
commit
b83283e081
@ -605,12 +605,15 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_citation_handles(self, sort_handles=False):
|
||||
def get_citation_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Citation in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Citation title.
|
||||
:param sort_handles: If True, the list is sorted by Citation title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@ -624,24 +627,30 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_family_handles(self, sort_handles=False):
|
||||
def get_family_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Family in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by surnames.
|
||||
:param sort_handles: If True, the list is sorted by surnames.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
|
||||
.. warning:: For speed the keys are directly returned, so handles are
|
||||
bytes type
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_media_handles(self, sort_handles=False):
|
||||
def get_media_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Media in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by title.
|
||||
:param sort_handles: If True, the list is sorted by title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
|
||||
.. warning:: For speed the keys are directly returned, so handles are
|
||||
bytes type
|
||||
@ -658,24 +667,30 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_person_handles(self, sort_handles=False):
|
||||
def get_person_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Person in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by surnames.
|
||||
:param sort_handles: If True, the list is sorted by surnames.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
|
||||
.. warning:: For speed the keys are directly returned, so handles are
|
||||
bytes type
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_place_handles(self, sort_handles=False):
|
||||
def get_place_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Place in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Place title.
|
||||
:param sort_handles: If True, the list is sorted by Place title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
|
||||
.. warning:: For speed the keys are directly returned, so handles are
|
||||
bytes type
|
||||
@ -692,24 +707,30 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_source_handles(self, sort_handles=False):
|
||||
def get_source_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Source in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Source title.
|
||||
:param sort_handles: If True, the list is sorted by Source title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
|
||||
.. warning:: For speed the keys are directly returned, so handles are
|
||||
bytes type
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_tag_handles(self, sort_handles=False):
|
||||
def get_tag_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Tag in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Tag name.
|
||||
:param sort_handles: If True, the list is sorted by Tag name.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
|
||||
.. warning:: For speed the keys are directly returned, so handles are
|
||||
bytes type
|
||||
|
@ -68,6 +68,7 @@ from .dbconst import DBLOGNAME
|
||||
from ..errors import HandleError
|
||||
from ..utils.callback import Callback
|
||||
from ..lib import Researcher
|
||||
from ..const import GRAMPS_LOCALE as glocale
|
||||
|
||||
LOG = logging.getLogger(DBLOGNAME)
|
||||
|
||||
@ -531,12 +532,15 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("handle %s does not exist in the dummy database", handle)
|
||||
raise HandleError('Handle %s not found' % handle)
|
||||
|
||||
def get_family_handles(self, sort_handles=False):
|
||||
def get_family_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Family in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by surnames.
|
||||
:param sort_handles: If True, the list is sorted by surnames.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if not self.db_is_open:
|
||||
LOG.warning("database is closed")
|
||||
@ -584,12 +588,15 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def get_media_handles(self, sort_handles=False):
|
||||
def get_media_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Media in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by title.
|
||||
:param sort_handles: If True, the list is sorted by title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if not self.db_is_open:
|
||||
LOG.warning("database is closed")
|
||||
@ -834,12 +841,15 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("handle %s does not exist in the dummy database", handle)
|
||||
raise HandleError('Handle %s not found' % handle)
|
||||
|
||||
def get_person_handles(self, sort_handles=False):
|
||||
def get_person_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Person in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by surnames.
|
||||
:param sort_handles: If True, the list is sorted by surnames.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if not self.db_is_open:
|
||||
LOG.warning("database is closed")
|
||||
@ -892,12 +902,15 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("handle %s does not exist in the dummy database", handle)
|
||||
raise HandleError('Handle %s not found' % handle)
|
||||
|
||||
def get_place_handles(self, sort_handles=False):
|
||||
def get_place_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Place in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Place title.
|
||||
:param sort_handles: If True, the list is sorted by Place title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if not self.db_is_open:
|
||||
LOG.warning("database is closed")
|
||||
@ -1102,12 +1115,15 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("handle %s does not exist in the dummy database", handle)
|
||||
raise HandleError('Handle %s not found' % handle)
|
||||
|
||||
def get_source_handles(self, sort_handles=False):
|
||||
def get_source_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Source in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Source title.
|
||||
:param sort_handles: If True, the list is sorted by Source title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if not self.db_is_open:
|
||||
LOG.warning("database is closed")
|
||||
@ -1160,12 +1176,15 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("handle %s does not exist in the dummy database", handle)
|
||||
raise HandleError('Handle %s not found' % handle)
|
||||
|
||||
def get_citation_handles(self, sort_handles=False):
|
||||
def get_citation_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Citation in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Citation title.
|
||||
:param sort_handles: If True, the list is sorted by Citation title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if not self.db_is_open:
|
||||
LOG.warning("database is closed")
|
||||
@ -1209,12 +1228,15 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("tag name %s does not exist in the dummy database", val)
|
||||
return None
|
||||
|
||||
def get_tag_handles(self, sort_handles=False):
|
||||
def get_tag_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Tag in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Tag name.
|
||||
:param sort_handles: If True, the list is sorted by Tag name.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if not self.db_is_open:
|
||||
LOG.warning("database is closed")
|
||||
|
@ -33,6 +33,7 @@ Proxy class for the Gramps databases. Apply filter
|
||||
from .proxybase import ProxyDbBase
|
||||
from ..lib import (Date, Person, Name, Surname, NameOriginType, Family, Source,
|
||||
Citation, Event, Media, Place, Repository, Note, Tag)
|
||||
from ..const import GRAMPS_LOCALE as glocale
|
||||
|
||||
class FilterProxyDb(ProxyDbBase):
|
||||
"""
|
||||
@ -385,10 +386,15 @@ class FilterProxyDb(ProxyDbBase):
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_person_handles(self, sort_handles=False):
|
||||
def get_person_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Person in
|
||||
the database. If sort_handles is True, the list is sorted by surnames
|
||||
the database.
|
||||
|
||||
:param sort_handles: If True, the list is sorted by surnames.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
# FIXME: plist is not a sorted list of handles
|
||||
return list(self.plist)
|
||||
@ -426,10 +432,15 @@ class FilterProxyDb(ProxyDbBase):
|
||||
"""
|
||||
return map(self.get_event_from_handle, self.elist)
|
||||
|
||||
def get_family_handles(self, sort_handles=False):
|
||||
def get_family_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Family in
|
||||
the database. If sort_handles is True, the list is sorted by surnames
|
||||
the database.
|
||||
|
||||
:param sort_handles: If True, the list is sorted by surnames.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
# FIXME: flist is not a sorted list of handles
|
||||
return list(self.flist)
|
||||
|
@ -38,6 +38,7 @@ import types
|
||||
from ..db.base import DbReadBase, DbWriteBase
|
||||
from ..lib import (Citation, Event, Family, Media, Note, Person, Place,
|
||||
Repository, Source, Tag)
|
||||
from ..const import GRAMPS_LOCALE as glocale
|
||||
|
||||
class ProxyCursor:
|
||||
"""
|
||||
@ -199,26 +200,28 @@ class ProxyDbBase(DbReadBase):
|
||||
return ProxyCursor(self.get_raw_tag_data,
|
||||
self.get_tag_handles)
|
||||
|
||||
def get_person_handles(self, sort_handles=False):
|
||||
def get_person_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Person in
|
||||
the database. If sort_handles is True, the list is sorted by surnames
|
||||
"""
|
||||
if (self.db is not None) and self.db.is_open():
|
||||
proxied = set(self.iter_person_handles())
|
||||
all = self.basedb.get_person_handles(sort_handles=sort_handles)
|
||||
all = self.basedb.get_person_handles(sort_handles=sort_handles,
|
||||
locale=locale)
|
||||
return [hdl for hdl in all if hdl in proxied]
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_family_handles(self, sort_handles=False):
|
||||
def get_family_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Family in
|
||||
the database. If sort_handles is True, the list is sorted by surnames
|
||||
"""
|
||||
if (self.db is not None) and self.db.is_open():
|
||||
proxied = set(self.iter_family_handles())
|
||||
all = self.basedb.get_family_handles(sort_handles=sort_handles)
|
||||
all = self.basedb.get_family_handles(sort_handles=sort_handles,
|
||||
locale=locale)
|
||||
return [hdl for hdl in all if hdl in proxied]
|
||||
else:
|
||||
return []
|
||||
@ -233,7 +236,7 @@ class ProxyDbBase(DbReadBase):
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_source_handles(self, sort_handles=False):
|
||||
def get_source_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Source in
|
||||
the database.
|
||||
@ -243,7 +246,7 @@ class ProxyDbBase(DbReadBase):
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_citation_handles(self, sort_handles=False):
|
||||
def get_citation_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Citation in
|
||||
the database.
|
||||
@ -253,7 +256,7 @@ class ProxyDbBase(DbReadBase):
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_place_handles(self, sort_handles=False):
|
||||
def get_place_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Place in
|
||||
the database.
|
||||
@ -263,7 +266,7 @@ class ProxyDbBase(DbReadBase):
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_media_handles(self, sort_handles=False):
|
||||
def get_media_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Media in
|
||||
the database.
|
||||
@ -293,7 +296,7 @@ class ProxyDbBase(DbReadBase):
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_tag_handles(self, sort_handles=False):
|
||||
def get_tag_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Tag in
|
||||
the database.
|
||||
|
@ -935,6 +935,12 @@ class GrampsLocale:
|
||||
return string
|
||||
return key
|
||||
|
||||
def get_collation(self):
|
||||
"""
|
||||
Return the collation without any character encoding.
|
||||
"""
|
||||
return self.collation.split('.')[0]
|
||||
|
||||
def strcoll(self, string1, string2):
|
||||
"""
|
||||
Given two localized strings, compare them and return -1 if
|
||||
|
@ -36,6 +36,7 @@ import os
|
||||
from sys import maxsize
|
||||
from operator import itemgetter
|
||||
import ast
|
||||
from functools import partial
|
||||
|
||||
try:
|
||||
from bsddb3 import db
|
||||
@ -1024,7 +1025,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
"""
|
||||
return [key.decode('utf-8') for key in table.keys(txn=self.txn)]
|
||||
|
||||
def get_person_handles(self, sort_handles=False):
|
||||
def get_person_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Person in
|
||||
the database.
|
||||
@ -1034,11 +1035,12 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
if self.db_is_open:
|
||||
handle_list = self._all_handles(self.person_map)
|
||||
if sort_handles:
|
||||
handle_list.sort(key=self.__sortbyperson_key)
|
||||
handle_list.sort(key=partial(self.__sortbyperson_key,
|
||||
locale=locale))
|
||||
return handle_list
|
||||
return []
|
||||
|
||||
def get_place_handles(self, sort_handles=False):
|
||||
def get_place_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Place in
|
||||
the database.
|
||||
@ -1049,11 +1051,12 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
if self.db_is_open:
|
||||
handle_list = self._all_handles(self.place_map)
|
||||
if sort_handles:
|
||||
handle_list.sort(key=self.__sortbyplace_key)
|
||||
handle_list.sort(key=partial(self.__sortbyplace_key,
|
||||
locale=locale))
|
||||
return handle_list
|
||||
return []
|
||||
|
||||
def get_source_handles(self, sort_handles=False):
|
||||
def get_source_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Source in
|
||||
the database.
|
||||
@ -1063,11 +1066,12 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
if self.db_is_open:
|
||||
handle_list = self._all_handles(self.source_map)
|
||||
if sort_handles:
|
||||
handle_list.sort(key=self.__sortbysource_key)
|
||||
handle_list.sort(key=partial(self.__sortbysource_key,
|
||||
locale=locale))
|
||||
return handle_list
|
||||
return []
|
||||
|
||||
def get_citation_handles(self, sort_handles=False):
|
||||
def get_citation_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Citation in
|
||||
the database.
|
||||
@ -1077,11 +1081,12 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
if self.db_is_open:
|
||||
handle_list = self._all_handles(self.citation_map)
|
||||
if sort_handles:
|
||||
handle_list.sort(key=self.__sortbycitation_key)
|
||||
handle_list.sort(key=partial(self.__sortbycitation_key,
|
||||
locale=locale))
|
||||
return handle_list
|
||||
return []
|
||||
|
||||
def get_media_handles(self, sort_handles=False):
|
||||
def get_media_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Media in
|
||||
the database.
|
||||
@ -1091,7 +1096,8 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
if self.db_is_open:
|
||||
handle_list = self._all_handles(self.media_map)
|
||||
if sort_handles:
|
||||
handle_list.sort(key=self.__sortbymedia_key)
|
||||
handle_list.sort(key=partial(self.__sortbymedia_key,
|
||||
locale=locale))
|
||||
return handle_list
|
||||
return []
|
||||
|
||||
@ -1104,7 +1110,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
return self._all_handles(self.event_map)
|
||||
return []
|
||||
|
||||
def get_family_handles(self, sort_handles=False):
|
||||
def get_family_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Family in
|
||||
the database.
|
||||
@ -1114,7 +1120,8 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
if self.db_is_open:
|
||||
handle_list = self._all_handles(self.family_map)
|
||||
if sort_handles:
|
||||
handle_list.sort(key=self.__sortbyfamily_key)
|
||||
handle_list.sort(key=partial(self.__sortbyfamily_key,
|
||||
locale=locale))
|
||||
return handle_list
|
||||
return []
|
||||
|
||||
@ -1136,7 +1143,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
return self._all_handles(self.note_map)
|
||||
return []
|
||||
|
||||
def get_tag_handles(self, sort_handles=False):
|
||||
def get_tag_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Tag in
|
||||
the database.
|
||||
@ -1146,7 +1153,8 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
if self.db_is_open:
|
||||
handle_list = self._all_handles(self.tag_map)
|
||||
if sort_handles:
|
||||
handle_list.sort(key=self.__sortbytag_key)
|
||||
handle_list.sort(key=partial(self.__sortbytag_key,
|
||||
locale=locale))
|
||||
return handle_list
|
||||
return []
|
||||
|
||||
@ -1774,24 +1782,24 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
"""
|
||||
return self.__has_gramps_id(self.cid_trans, gramps_id)
|
||||
|
||||
def __sortbyperson_key(self, handle):
|
||||
def __sortbyperson_key(self, handle, locale=glocale):
|
||||
handle = handle.encode('utf-8')
|
||||
return glocale.sort_key(find_fullname(handle,
|
||||
self.person_map.get(handle)))
|
||||
return locale.sort_key(find_fullname(handle,
|
||||
self.person_map.get(handle)))
|
||||
|
||||
def __sortbyfamily_key(self, handle):
|
||||
def __sortbyfamily_key(self, handle, locale=glocale):
|
||||
handle = handle.encode('utf-8')
|
||||
data = self.family_map.get(handle)
|
||||
data2 = data[2]
|
||||
data3 = data[3]
|
||||
if data2: # father handle
|
||||
data2 = data2.encode('utf-8')
|
||||
return glocale.sort_key(find_fullname(data2,
|
||||
self.person_map.get(data2)))
|
||||
return locale.sort_key(find_fullname(data2,
|
||||
self.person_map.get(data2)))
|
||||
elif data3: # mother handle
|
||||
data3 = data3.encode('utf-8')
|
||||
return glocale.sort_key(find_fullname(data3,
|
||||
self.person_map.get(data3)))
|
||||
return locale.sort_key(find_fullname(data3,
|
||||
self.person_map.get(data3)))
|
||||
return ''
|
||||
|
||||
def __sortbyplace(self, first, second):
|
||||
@ -1800,9 +1808,9 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
return glocale.strcoll(self.place_map.get(first)[2],
|
||||
self.place_map.get(second)[2])
|
||||
|
||||
def __sortbyplace_key(self, place):
|
||||
def __sortbyplace_key(self, place, locale=glocale):
|
||||
place = place.encode('utf-8')
|
||||
return glocale.sort_key(self.place_map.get(place)[2])
|
||||
return locale.sort_key(self.place_map.get(place)[2])
|
||||
|
||||
def __sortbysource(self, first, second):
|
||||
first = first.encode('utf-8')
|
||||
@ -1811,10 +1819,10 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
source2 = str(self.source_map[second][2])
|
||||
return glocale.strcoll(source1, source2)
|
||||
|
||||
def __sortbysource_key(self, key):
|
||||
def __sortbysource_key(self, key, locale=glocale):
|
||||
key = key.encode('utf-8')
|
||||
source = str(self.source_map[key][2])
|
||||
return glocale.sort_key(source)
|
||||
return locale.sort_key(source)
|
||||
|
||||
def __sortbycitation(self, first, second):
|
||||
first = first.encode('utf-8')
|
||||
@ -1823,10 +1831,10 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
citation2 = str(self.citation_map[second][3])
|
||||
return glocale.strcoll(citation1, citation2)
|
||||
|
||||
def __sortbycitation_key(self, key):
|
||||
def __sortbycitation_key(self, key, locale=glocale):
|
||||
key = key.encode('utf-8')
|
||||
citation = str(self.citation_map[key][3])
|
||||
return glocale.sort_key(citation)
|
||||
return locale.sort_key(citation)
|
||||
|
||||
def __sortbymedia(self, first, second):
|
||||
first = first.encode('utf-8')
|
||||
@ -1835,10 +1843,10 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
media2 = self.media_map[second][4]
|
||||
return glocale.strcoll(media1, media2)
|
||||
|
||||
def __sortbymedia_key(self, key):
|
||||
def __sortbymedia_key(self, key, locale=glocale):
|
||||
key = key.encode('utf-8')
|
||||
media = self.media_map[key][4]
|
||||
return glocale.sort_key(media)
|
||||
return locale.sort_key(media)
|
||||
|
||||
def __sortbytag(self, first, second):
|
||||
first = first.encode('utf-8')
|
||||
@ -1847,10 +1855,10 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
tag2 = self.tag_map[second][1]
|
||||
return glocale.strcoll(tag1, tag2)
|
||||
|
||||
def __sortbytag_key(self, key):
|
||||
def __sortbytag_key(self, key, locale=glocale):
|
||||
key = key.encode('utf-8')
|
||||
tag = self.tag_map[key][1]
|
||||
return glocale.sort_key(tag)
|
||||
return locale.sort_key(tag)
|
||||
|
||||
def set_mediapath(self, path):
|
||||
"""Set the default media path for database."""
|
||||
|
@ -401,44 +401,57 @@ class DBAPI(DbGeneric):
|
||||
else:
|
||||
return key
|
||||
|
||||
def get_person_handles(self, sort_handles=False):
|
||||
def get_person_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Person in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by surnames.
|
||||
:param sort_handles: If True, the list is sorted by surnames.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
self.dbapi.execute("SELECT handle FROM person "
|
||||
"ORDER BY surname COLLATE glocale")
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM person '
|
||||
'ORDER BY surname '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM person")
|
||||
rows = self.dbapi.fetchall()
|
||||
return [row[0] for row in rows]
|
||||
|
||||
def get_family_handles(self, sort_handles=False):
|
||||
def get_family_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Family in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by surnames.
|
||||
:param sort_handles: If True, the list is sorted by surnames.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
sql = ("SELECT family.handle " +
|
||||
"FROM family " +
|
||||
"LEFT JOIN person AS father " +
|
||||
"ON family.father_handle = father.handle " +
|
||||
"LEFT JOIN person AS mother " +
|
||||
"ON family.mother_handle = mother.handle " +
|
||||
"ORDER BY (CASE WHEN father.handle IS NULL " +
|
||||
"THEN mother.surname " +
|
||||
"ELSE father.surname " +
|
||||
"END), " +
|
||||
"(CASE WHEN family.handle IS NULL " +
|
||||
"THEN mother.given_name " +
|
||||
"ELSE father.given_name " +
|
||||
"END) " +
|
||||
"COLLATE glocale")
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
sql = ('SELECT family.handle ' +
|
||||
'FROM family ' +
|
||||
'LEFT JOIN person AS father ' +
|
||||
'ON family.father_handle = father.handle ' +
|
||||
'LEFT JOIN person AS mother ' +
|
||||
'ON family.mother_handle = mother.handle ' +
|
||||
'ORDER BY (CASE WHEN father.handle IS NULL ' +
|
||||
'THEN mother.surname ' +
|
||||
'ELSE father.surname ' +
|
||||
'END), ' +
|
||||
'(CASE WHEN family.handle IS NULL ' +
|
||||
'THEN mother.given_name ' +
|
||||
'ELSE father.given_name ' +
|
||||
'END) ' +
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
self.dbapi.execute(sql)
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM family")
|
||||
@ -454,46 +467,67 @@ class DBAPI(DbGeneric):
|
||||
rows = self.dbapi.fetchall()
|
||||
return [row[0] for row in rows]
|
||||
|
||||
def get_citation_handles(self, sort_handles=False):
|
||||
def get_citation_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Citation in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Citation title.
|
||||
:param sort_handles: If True, the list is sorted by Citation title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
self.dbapi.execute("SELECT handle FROM citation "
|
||||
"ORDER BY page COLLATE glocale")
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM citation '
|
||||
'ORDER BY page '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM citation")
|
||||
rows = self.dbapi.fetchall()
|
||||
return [row[0] for row in rows]
|
||||
|
||||
def get_source_handles(self, sort_handles=False):
|
||||
def get_source_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Source in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Source title.
|
||||
:param sort_handles: If True, the list is sorted by Source title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
self.dbapi.execute("SELECT handle FROM source "
|
||||
"ORDER BY title COLLATE glocale")
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM source '
|
||||
'ORDER BY title '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle from source")
|
||||
rows = self.dbapi.fetchall()
|
||||
return [row[0] for row in rows]
|
||||
|
||||
def get_place_handles(self, sort_handles=False):
|
||||
def get_place_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Place in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Place title.
|
||||
:param sort_handles: If True, the list is sorted by Place title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
self.dbapi.execute("SELECT handle FROM place "
|
||||
"ORDER BY title COLLATE glocale")
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM place '
|
||||
'ORDER BY title '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM place")
|
||||
rows = self.dbapi.fetchall()
|
||||
@ -508,16 +542,23 @@ class DBAPI(DbGeneric):
|
||||
rows = self.dbapi.fetchall()
|
||||
return [row[0] for row in rows]
|
||||
|
||||
def get_media_handles(self, sort_handles=False):
|
||||
def get_media_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Media in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by title.
|
||||
:param sort_handles: If True, the list is sorted by title.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
self.dbapi.execute("SELECT handle FROM media "
|
||||
"ORDER BY desc COLLATE glocale")
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM media '
|
||||
'ORDER BY desc '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM media")
|
||||
rows = self.dbapi.fetchall()
|
||||
@ -532,16 +573,23 @@ class DBAPI(DbGeneric):
|
||||
rows = self.dbapi.fetchall()
|
||||
return [row[0] for row in rows]
|
||||
|
||||
def get_tag_handles(self, sort_handles=False):
|
||||
def get_tag_handles(self, sort_handles=False, locale=glocale):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Tag in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Tag name.
|
||||
:param sort_handles: If True, the list is sorted by Tag name.
|
||||
:type sort_handles: bool
|
||||
:param locale: The locale to use for collation.
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
self.dbapi.execute("SELECT handle FROM tag "
|
||||
"ORDER BY name COLLATE glocale")
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM tag '
|
||||
'ORDER BY name '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM tag")
|
||||
rows = self.dbapi.fetchall()
|
||||
|
@ -26,7 +26,6 @@
|
||||
#-------------------------------------------------------------------------
|
||||
import psycopg2
|
||||
import re
|
||||
import os
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -34,6 +33,7 @@ import os
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.db.dbconst import ARRAYSIZE
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
|
||||
psycopg2.paramstyle = 'format'
|
||||
|
||||
@ -57,9 +57,24 @@ class Postgresql:
|
||||
self.__connection = psycopg2.connect(*args, **kwargs)
|
||||
self.__connection.autocommit = True
|
||||
self.__cursor = self.__connection.cursor()
|
||||
locale = os.environ.get('LANG', 'en_US.utf8')
|
||||
self.execute("DROP COLLATION IF EXISTS glocale")
|
||||
self.execute("CREATE COLLATION glocale (LOCALE = '%s')" % locale)
|
||||
self.check_collation(glocale)
|
||||
|
||||
def check_collation(self, locale):
|
||||
"""
|
||||
Checks that a collation exists and if not creates it.
|
||||
|
||||
:param locale: Locale to be checked.
|
||||
:param type: A GrampsLocale object.
|
||||
"""
|
||||
# Duplicating system collations works, but to delete them the schema
|
||||
# must be specified, so get the current schema
|
||||
self.execute('SELECT current_schema()')
|
||||
current_schema, = self.fetchone()
|
||||
collation = locale.get_collation()
|
||||
self.execute('DROP COLLATION IF EXISTS "%s"."%s"'
|
||||
% (current_schema, collation))
|
||||
self.execute('CREATE COLLATION "%s"'
|
||||
"(LOCALE = '%s')" % (collation, locale.collation))
|
||||
|
||||
def _hack_query(self, query):
|
||||
query = query.replace("?", "%s")
|
||||
|
@ -83,8 +83,20 @@ class Sqlite:
|
||||
self.log = logging.getLogger(".sqlite")
|
||||
self.__connection = sqlite3.connect(*args, **kwargs)
|
||||
self.__cursor = self.__connection.cursor()
|
||||
self.__connection.create_collation("glocale", glocale.strcoll)
|
||||
self.__connection.create_function("regexp", 2, regexp)
|
||||
self.__collations = []
|
||||
self.check_collation(glocale)
|
||||
|
||||
def check_collation(self, locale):
|
||||
"""
|
||||
Checks that a collation exists and if not creates it.
|
||||
|
||||
:param locale: Locale to be checked.
|
||||
:param type: A GrampsLocale object.
|
||||
"""
|
||||
collation = locale.get_collation()
|
||||
if collation not in self.__collations:
|
||||
self.__connection.create_collation(collation, locale.strcoll)
|
||||
|
||||
def execute(self, *args, **kwargs):
|
||||
"""
|
||||
|
@ -660,7 +660,8 @@ class FamilyGroup(Report):
|
||||
self.dump_family(child_family_handle, (generation+1))
|
||||
|
||||
def write_report(self):
|
||||
flist = self.db.get_family_handles(sort_handles=True)
|
||||
flist = self.db.get_family_handles(sort_handles=True,
|
||||
locale=self._locale)
|
||||
if not self.filter:
|
||||
fam_list = flist
|
||||
else:
|
||||
|
@ -815,7 +815,8 @@ class IndivCompleteReport(Report):
|
||||
|
||||
def write_report(self):
|
||||
""" write the report """
|
||||
plist = self._db.get_person_handles(sort_handles=True)
|
||||
plist = self._db.get_person_handles(sort_handles=True,
|
||||
locale=self._locale)
|
||||
if self.filter:
|
||||
ind_list = self.filter.apply(self._db, plist, user=self._user)
|
||||
else:
|
||||
|
@ -542,7 +542,8 @@ class TagReport(Report):
|
||||
|
||||
def write_media(self):
|
||||
""" write the media associated with the tag """
|
||||
mlist = self.database.get_media_handles(sort_handles=True)
|
||||
mlist = self.database.get_media_handles(sort_handles=True,
|
||||
locale=self._locale)
|
||||
filter_class = GenericFilterFactory('Media')
|
||||
a_filter = filter_class()
|
||||
a_filter.add_rule(rules.media.HasTag([self.tag]))
|
||||
@ -711,7 +712,8 @@ class TagReport(Report):
|
||||
|
||||
def write_sources(self):
|
||||
""" write the sources associated with the tag """
|
||||
slist = self.database.get_source_handles(sort_handles=True)
|
||||
slist = self.database.get_source_handles(sort_handles=True,
|
||||
locale=self._locale)
|
||||
filter_class = GenericFilterFactory('Source')
|
||||
a_filter = filter_class()
|
||||
a_filter.add_rule(rules.source.HasTag([self.tag]))
|
||||
@ -791,7 +793,8 @@ class TagReport(Report):
|
||||
|
||||
def write_citations(self):
|
||||
""" write the citations associated with the tag """
|
||||
clist = self.database.get_citation_handles(sort_handles=True)
|
||||
clist = self.database.get_citation_handles(sort_handles=True,
|
||||
locale=self._locale)
|
||||
filter_class = GenericFilterFactory('Citation')
|
||||
a_filter = filter_class()
|
||||
a_filter.add_rule(rules.citation.HasTag([self.tag]))
|
||||
|
Loading…
Reference in New Issue
Block a user