Package gen :: Package db :: Module base
[frames] | no frames]

Source Code for Module gen.db.base

   1  # 
   2  # Gramps - a GTK+/GNOME based genealogy program 
   3  # 
   4  # Copyright (C) 2000-2007  Donald N. Allingham 
   5  # 
   6  # This program is free software; you can redistribute it and/or modify 
   7  # it under the terms of the GNU General Public License as published by 
   8  # the Free Software Foundation; either version 2 of the License, or 
   9  # (at your option) any later version. 
  10  # 
  11  # This program is distributed in the hope that it will be useful,  
  12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  14  # GNU General Public License for more details. 
  15  # 
  16  # You should have received a copy of the GNU General Public License 
  17  # along with this program; if not, write to the Free Software 
  18  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  19  # 
  20   
  21  # $Id: base.py 10236 2008-03-09 18:10:13Z bmcage $ 
  22   
  23  """ 
  24  Base class for the GRAMPS databases. All database interfaces should inherit 
  25  from this class. 
  26  """ 
  27   
  28  #------------------------------------------------------------------------- 
  29  # 
  30  # libraries 
  31  # 
  32  #------------------------------------------------------------------------- 
  33  import cPickle 
  34  import time 
  35  import random 
  36  import locale 
  37  import os 
  38  from sys import maxint 
  39  from bsddb import db 
  40  from gettext import gettext as _ 
  41   
  42  import logging 
  43  LOG = logging.getLogger(".GrampsDb") 
  44   
  45  #------------------------------------------------------------------------- 
  46  # 
  47  # GRAMPS libraries 
  48  # 
  49  #------------------------------------------------------------------------- 
  50  from gen.lib import (MediaObject, Person, Family, Source, Event, Place,  
  51                       Repository, Note, GenderStats, Researcher) 
  52  from gen.utils.callback import Callback 
  53  from gen.db.iterator import CursorIterator 
  54   
  55  #------------------------------------------------------------------------- 
  56  # 
  57  # constants 
  58  # 
  59  #------------------------------------------------------------------------- 
  60  from gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY,  
  61                              MEDIA_KEY, PLACE_KEY, REPOSITORY_KEY, NOTE_KEY,  
  62                              REFERENCE_KEY, PERSON_COL_KEY, FAMILY_COL_KEY,  
  63                              CHILD_COL_KEY, PLACE_COL_KEY, SOURCE_COL_KEY,  
  64                              MEDIA_COL_KEY, EVENT_COL_KEY, REPOSITORY_COL_KEY,  
  65                              NOTE_COL_KEY) 
  66   
  67  _UNDO_SIZE = 1000 
  68   
  69   
  70  # The following two dictionaries provide fast translation 
  71  # between the primary class names and the keys used to reference 
  72  # these classes in the database tables. Beware that changing 
  73  # these maps or modifying the values of the keys will break 
  74  # existing databases. 
  75   
  76  CLASS_TO_KEY_MAP = {Person.__name__: PERSON_KEY,  
  77                      Family.__name__: FAMILY_KEY,  
  78                      Source.__name__: SOURCE_KEY,  
  79                      Event.__name__: EVENT_KEY,  
  80                      MediaObject.__name__: MEDIA_KEY,  
  81                      Place.__name__: PLACE_KEY,  
  82                      Repository.__name__:REPOSITORY_KEY, 
  83                      Note.__name__: NOTE_KEY} 
  84   
  85  KEY_TO_CLASS_MAP = {PERSON_KEY: Person.__name__,  
  86                      FAMILY_KEY: Family.__name__,  
  87                      SOURCE_KEY: Source.__name__,  
  88                      EVENT_KEY: Event.__name__,  
  89                      MEDIA_KEY: MediaObject.__name__,  
  90                      PLACE_KEY: Place.__name__,  
  91                      REPOSITORY_KEY: Repository.__name__, 
  92                      NOTE_KEY: Note.__name__} 
  93   
  94  _SIGBASE = ('person', 'family', 'source', 'event',  
  95              'media', 'place', 'repository', 'reference', 'note') 
  96   
97 -class GrampsDbBookmarks:
98 - def __init__(self, default=[]):
99 self.bookmarks = list(default) # want a copy (not an alias)
100
101 - def set(self, new_list):
102 self.bookmarks = list(new_list)
103
104 - def get(self):
105 return self.bookmarks
106
107 - def append(self, item):
108 self.bookmarks.append(item)
109
110 - def append_list(self, blist):
111 self.bookmarks += blist
112
113 - def remove(self, item):
114 self.bookmarks.remove(item)
115
116 - def pop(self, item):
117 return self.bookmarks.pop(item)
118
119 - def insert(self, pos, item):
120 self.bookmarks.insert(pos, item)
121
122 -class GrampsDbBase(Callback):
123 """ 124 GRAMPS database object. This object is a base class for all 125 database interfaces. 126 """ 127 128 # This holds a reference to the gramps Config module if 129 # it is available, it is setup by the factory methods. 130 __config__ = None 131 132 __signals__ = { 133 'person-add' : (list, ), 134 'person-update' : (list, ), 135 'person-delete' : (list, ), 136 'person-rebuild' : None, 137 'family-add' : (list, ), 138 'family-update' : (list, ), 139 'family-delete' : (list, ), 140 'family-rebuild' : None, 141 'source-add' : (list, ), 142 'source-update' : (list, ), 143 'source-delete' : (list, ), 144 'source-rebuild' : None, 145 'place-add' : (list, ), 146 'place-update' : (list, ), 147 'place-delete' : (list, ), 148 'place-rebuild' : None, 149 'media-add' : (list, ), 150 'media-update' : (list, ), 151 'media-delete' : (list, ), 152 'media-rebuild' : None, 153 'event-add' : (list, ), 154 'event-update' : (list, ), 155 'event-delete' : (list, ), 156 'event-rebuild' : None, 157 'repository-add' : (list, ), 158 'repository-update' : (list, ), 159 'repository-delete' : (list, ), 160 'repository-rebuild' : None, 161 'note-add' : (list, ), 162 'note-update' : (list, ), 163 'note-delete' : (list, ), 164 'note-rebuild' : None, 165 'long-op-start' : (object, ), 166 'long-op-heartbeat' : None, 167 'long-op-end' : None 168 } 169 170 # If this is True logging will be turned on. 171 try: 172 _LOG_ALL = int(os.environ.get('GRAMPS_SIGNAL', "0")) == 1 173 except: 174 _LOG_ALL = False 175 176
177 - def __init__(self):
178 """ 179 Create a new GrampsDbBase instance. 180 181 A new GrampDbBase class should never be directly created. Only classes 182 derived from this class should be created. 183 """ 184 185 Callback.__init__(self) 186 187 self.set_person_id_prefix('I%04d') 188 self.set_object_id_prefix('O%04d') 189 self.set_family_id_prefix('F%04d') 190 self.set_source_id_prefix('S%04d') 191 self.set_place_id_prefix('P%04d') 192 self.set_event_id_prefix('E%04d') 193 self.set_repository_id_prefix('R%04d') 194 self.set_note_id_prefix('N%04d') 195 196 self.readonly = False 197 self.rand = random.Random(time.time()) 198 self.smap_index = 0 199 self.emap_index = 0 200 self.pmap_index = 0 201 self.fmap_index = 0 202 self.lmap_index = 0 203 self.omap_index = 0 204 self.rmap_index = 0 205 self.nmap_index = 0 206 self.db_is_open = False 207 208 self.family_event_names = set() 209 self.individual_event_names = set() 210 self.individual_attributes = set() 211 self.family_attributes = set() 212 self.marker_names = set() 213 self.child_ref_types = set() 214 self.family_rel_types = set() 215 self.event_role_names = set() 216 self.name_types = set() 217 self.repository_types = set() 218 self.note_types = set() 219 self.source_media_types = set() 220 self.url_types = set() 221 self.media_attributes = set() 222 223 self.open = 0 224 self.genderStats = GenderStats() 225 226 self.undodb = [] 227 self.id_trans = {} 228 self.fid_trans = {} 229 self.pid_trans = {} 230 self.sid_trans = {} 231 self.oid_trans = {} 232 self.rid_trans = {} 233 self.nid_trans = {} 234 self.eid_trans = {} 235 self.env = None 236 self.person_map = {} 237 self.family_map = {} 238 self.place_map = {} 239 self.source_map = {} 240 self.repository_map = {} 241 self.note_map = {} 242 self.media_map = {} 243 self.event_map = {} 244 self.metadata = {} 245 self.name_group = {} 246 self.undo_callback = None 247 self.redo_callback = None 248 self.undo_history_callback = None 249 self.modified = 0 250 251 self.undoindex = -1 252 self.translist = [None] * _UNDO_SIZE 253 self.abort_possible = True 254 self.undo_history_timestamp = 0 255 self.default = None 256 self.owner = Researcher() 257 self.name_formats = [] 258 self.bookmarks = GrampsDbBookmarks() 259 self.family_bookmarks = GrampsDbBookmarks() 260 self.event_bookmarks = GrampsDbBookmarks() 261 self.place_bookmarks = GrampsDbBookmarks() 262 self.source_bookmarks = GrampsDbBookmarks() 263 self.repo_bookmarks = GrampsDbBookmarks() 264 self.media_bookmarks = GrampsDbBookmarks() 265 self.note_bookmarks = GrampsDbBookmarks() 266 self._bm_changes = 0 267 self.path = "" 268 self.surname_list = []
269
270 - def set_prefixes(self, person, media, family, source, place, event, 271 repository, note):
272 self.person_prefix = person 273 self.mediaobject_prefix = media 274 self.family_prefix = family 275 self.source_prefix = source 276 self.place_prefix = place 277 self.event_prefix = event 278 self.repository_prefix = repository 279 self.note_prefix = note
280
281 - def rebuild_secondary(self, callback):
282 pass
283
284 - def version_supported(self):
285 """Return True when the file has a supported version.""" 286 return True
287
288 - def need_upgrade(self):
289 return False
290
291 - def gramps_upgrade(self):
292 pass
293
294 - def del_person(self, handle):
295 pass
296
297 - def del_source(self, handle):
298 pass
299
300 - def del_repository(self, handle):
301 pass
302
303 - def del_note(self, handle):
304 pass
305
306 - def del_place(self, handle):
307 pass
308
309 - def del_media(self, handle):
310 pass
311
312 - def del_family(self, handle):
313 pass
314
315 - def del_event(self, handle):
316 pass
317
318 - def create_id(self):
319 return "%08x%08x" % ( int(time.time()*10000), 320 self.rand.randint(0, maxint))
321
322 - def get_person_cursor(self):
323 raise NotImplementedError
324
325 - def get_person_cursor_iter(self, msg=_("Processing Person records")):
326 return CursorIterator(self, self.get_person_cursor(), msg)
327
328 - def get_family_cursor(self):
329 raise NotImplementedError
330
331 - def get_family_cursor_iter(self, msg=_("Processing Family records")):
332 return CursorIterator(self, self.get_family_cursor(), msg)
333
334 - def get_event_cursor(self):
335 raise NotImplementedError
336
337 - def get_event_cursor_iter(self, msg=_("Processing Event records")):
338 return CursorIterator(self, self.get_event_cursor(), msg)
339
340 - def get_place_cursor(self):
341 raise NotImplementedError
342
343 - def get_place_cursor_iter(self, msg=_("Processing Place records")):
344 return CursorIterator(self, self.get_place_cursor(), msg)
345
346 - def get_source_cursor(self):
347 raise NotImplementedError
348
349 - def get_source_cursor_iter(self, msg=_("Processing Source records")):
350 return CursorIterator(self, self.get_source_cursor(), msg)
351
352 - def get_media_cursor(self):
353 raise NotImplementedError
354
355 - def get_media_cursor_iter(self, msg=_("Processing Media records")):
356 return CursorIterator(self, self.get_media_cursor(), msg)
357
358 - def get_repository_cursor(self):
359 raise NotImplementedError
360
361 - def get_repository_cursor_iter(self, msg=_("Processing Repository records")):
362 return CursorIterator(self, self.get_repository_cursor(), msg)
363
364 - def get_note_cursor(self):
365 raise NotImplementedError
366
367 - def get_note_cursor_iter(self, msg=_("Processing Note records")):
368 return CursorIterator(self, self.get_note_cursor(), msg)
369
370 - def open_undodb(self):
371 if not self.readonly: 372 self.undolog = "%s.undo" % self.full_name 373 self.undodb = db.DB() 374 self.undodb.open(self.undolog, db.DB_RECNO, db.DB_CREATE)
375
376 - def close_undodb(self):
377 if not self.readonly: 378 self.undodb.close() 379 try: 380 os.remove(self.undolog) 381 except: 382 pass
383
384 - def load(self, name, callback, mode="w"):
385 """ 386 Open the specified database. 387 388 The method needs to be overridden in the derived class. 389 """ 390 raise NotImplementedError
391
392 - def load_from(self, other_database, filename, callback):
393 """ 394 Load data from the other database into itself. 395 396 The filename is the name of the file for the newly created database. 397 The method needs to be overridden in the derived class. 398 """ 399 raise NotImplementedError
400
401 - def close(self):
402 """ 403 Close the specified database. 404 405 The method needs to be overridden in the derived class. 406 """ 407 pass
408
409 - def is_open(self):
410 """ 411 Return 1 if the database has been opened. 412 """ 413 return self.db_is_open
414
415 - def request_rebuild(self):
416 """ 417 Notify clients that the data has changed significantly, and that all 418 internal data dependent on the database should be rebuilt. 419 """ 420 self.emit('person-rebuild') 421 self.emit('family-rebuild') 422 self.emit('place-rebuild') 423 self.emit('source-rebuild') 424 self.emit('media-rebuild') 425 self.emit('event-rebuild') 426 self.emit('repository-rebuild') 427 self.emit('note-rebuild')
428
429 - def commit_base(self, obj, data_map, key, update_list, add_list, 430 transaction, change_time):
431 """ 432 Commit the specified Person to the database, storing the changes as 433 part of the transaction. 434 """ 435 if self.readonly or not obj or not obj.handle: 436 return 437 438 if change_time: 439 obj.change = int(change_time) 440 else: 441 obj.change = int(time.time()) 442 handle = str(obj.handle) 443 444 self.update_reference_map(obj, transaction) 445 446 if transaction.batch: 447 data_map[handle] = obj.serialize() 448 old_data = None 449 else: 450 old_data = data_map.get(handle) 451 new_data = obj.serialize() 452 transaction.add(key, handle, old_data, new_data) 453 if old_data: 454 update_list.append((handle, new_data)) 455 else: 456 add_list.append((handle, new_data)) 457 return old_data
458
459 - def commit_person(self, person, transaction, change_time=None):
460 """ 461 Commit the specified Person to the database, storing the changes as 462 part of the transaction. 463 """ 464 465 old_data = self.commit_base( 466 person, self.person_map, PERSON_KEY, transaction.person_update, 467 transaction.person_add, transaction, change_time) 468 if old_data: 469 old_person = Person(old_data) 470 if (old_data[2] != person.gender or 471 old_data[3][4]!= person.primary_name.first_name): 472 self.genderStats.uncount_person(old_person) 473 self.genderStats.count_person(person) 474 if (old_data[3][5]!=person.primary_name.surname): 475 self.remove_from_surname_list(old_person) 476 self.add_to_surname_list(person, transaction.batch) 477 else: 478 self.genderStats.count_person(person) 479 self.add_to_surname_list(person, transaction.batch) 480 481 self.individual_attributes.update( 482 [str(attr.type) for attr in person.attribute_list 483 if attr.type.is_custom() and str(attr.type)]) 484 485 if person.marker.is_custom(): 486 self.marker_names.add(str(person.marker)) 487 488 self.event_role_names.update([str(eref.role) 489 for eref in person.event_ref_list 490 if eref.role.is_custom()]) 491 492 self.name_types.update([str(name.type) 493 for name in ([person.primary_name] 494 + person.alternate_names) 495 if name.type.is_custom()]) 496 497 self.url_types.update([str(url.type) for url in person.urls 498 if url.type.is_custom()]) 499 500 attr_list = [] 501 for mref in person.media_list: 502 attr_list += [str(attr.type) for attr in mref.attribute_list 503 if attr.type.is_custom() and str(attr.type)] 504 self.media_attributes.update(attr_list)
505
506 - def commit_media_object(self, obj, transaction, change_time=None):
507 """ 508 Commit the specified MediaObject to the database, storing the changes 509 as part of the transaction. 510 """ 511 512 self.commit_base(obj, self.media_map, MEDIA_KEY, 513 transaction.media_update, transaction.media_add, 514 transaction, change_time) 515 self.media_attributes.update( 516 [str(attr.type) for attr in obj.attribute_list 517 if attr.type.is_custom() and str(attr.type)])
518
519 - def commit_source(self, source, transaction, change_time=None):
520 """ 521 Commit the specified Source to the database, storing the changes as 522 part of the transaction. 523 """ 524 525 self.commit_base(source, self.source_map, SOURCE_KEY, 526 transaction.source_update, transaction.source_add, 527 transaction, change_time) 528 529 self.source_media_types.update( 530 [str(ref.media_type) for ref in source.reporef_list 531 if ref.media_type.is_custom()]) 532 533 attr_list = [] 534 for mref in source.media_list: 535 attr_list += [str(attr.type) for attr in mref.attribute_list 536 if attr.type.is_custom() and str(attr.type)] 537 self.media_attributes.update(attr_list)
538
539 - def commit_place(self, place, transaction, change_time=None):
540 """ 541 Commit the specified Place to the database, storing the changes as 542 part of the transaction. 543 """ 544 545 self.commit_base(place, self.place_map, PLACE_KEY, 546 transaction.place_update, transaction.place_add, 547 transaction, change_time) 548 549 self.url_types.update([str(url.type) for url in place.urls 550 if url.type.is_custom()]) 551 552 attr_list = [] 553 for mref in place.media_list: 554 attr_list += [str(attr.type) for attr in mref.attribute_list 555 if attr.type.is_custom() and str(attr.type)] 556 self.media_attributes.update(attr_list)
557
558 - def commit_personal_event(self, event, transaction, change_time=None):
559 if event.type.is_custom(): 560 self.individual_event_names.add(str(event.type)) 561 self.commit_event(event, transaction, change_time)
562
563 - def commit_family_event(self, event, transaction, change_time=None):
564 if event.type.is_custom(): 565 self.family_event_names.add(str(event.type)) 566 self.commit_event(event, transaction, change_time)
567
568 - def commit_event(self, event, transaction, change_time=None):
569 """ 570 Commit the specified Event to the database, storing the changes as 571 part of the transaction. 572 """ 573 self.commit_base(event, self.event_map, EVENT_KEY, 574 transaction.event_update, transaction.event_add, 575 transaction, change_time) 576 577 attr_list = [] 578 for mref in event.media_list: 579 attr_list += [str(attr.type) for attr in mref.attribute_list 580 if attr.type.is_custom() and str(attr.type)] 581 self.media_attributes.update(attr_list)
582
583 - def commit_family(self, family, transaction, change_time=None):
584 """ 585 Commit the specified Family to the database, storing the changes as 586 part of the transaction. 587 """ 588 589 self.commit_base(family, self.family_map, FAMILY_KEY, 590 transaction.family_update, transaction.family_add, 591 transaction, change_time) 592 593 self.family_attributes.update( 594 [str(attr.type) for attr in family.attribute_list 595 if attr.type.is_custom() and str(attr.type)]) 596 597 rel_list = [] 598 for ref in family.child_ref_list: 599 if ref.frel.is_custom(): 600 rel_list.append(str(ref.frel)) 601 if ref.mrel.is_custom(): 602 rel_list.append(str(ref.mrel)) 603 self.child_ref_types.update(rel_list) 604 605 self.event_role_names.update( 606 [str(eref.role) for eref in family.event_ref_list 607 if eref.role.is_custom()]) 608 609 if family.type.is_custom(): 610 self.family_rel_types.add(str(family.type)) 611 612 attr_list = [] 613 for mref in family.media_list: 614 attr_list += [str(attr.type) for attr in mref.attribute_list 615 if attr.type.is_custom() and str(attr.type)] 616 self.media_attributes.update(attr_list)
617
618 - def commit_repository(self, repository, transaction, change_time=None):
619 """ 620 Commit the specified Repository to the database, storing the changes 621 as part of the transaction. 622 """ 623 self.commit_base(repository, self.repository_map, REPOSITORY_KEY, 624 transaction.repository_update, 625 transaction.repository_add, 626 transaction, change_time) 627 628 if repository.type.is_custom(): 629 self.repository_types.add(str(repository.type)) 630 631 self.url_types.update([str(url.type) for url in repository.urls 632 if url.type.is_custom()])
633
634 - def commit_note(self, note, transaction, change_time=None):
635 """ 636 Commit the specified Note to the database, storing the changes as part 637 of the transaction. 638 """ 639 self.commit_base(note, self.note_map, NOTE_KEY, 640 transaction.note_update, 641 transaction.note_add, 642 transaction, change_time) 643 644 if note.type.is_custom(): 645 self.note_types.add(str(note.type))
646
647 - def find_next_person_gramps_id(self):
648 """ 649 Return the next available GRAMPS' ID for a Person object based off the 650 person ID prefix. 651 """ 652 index = self.person_prefix % self.pmap_index 653 while self.id_trans.has_key(str(index)): 654 self.pmap_index += 1 655 index = self.person_prefix % self.pmap_index 656 self.pmap_index += 1 657 return index
658
659 - def find_next_place_gramps_id(self):
660 """ 661 Return the next available GRAMPS' ID for a Place object based off the 662 place ID prefix. 663 """ 664 index = self.place_prefix % self.lmap_index 665 while self.pid_trans.has_key(str(index)): 666 self.lmap_index += 1 667 index = self.place_prefix % self.lmap_index 668 self.lmap_index += 1 669 return index
670
671 - def find_next_event_gramps_id(self):
672 """ 673 Return the next available GRAMPS' ID for a Event object based off the 674 event ID prefix. 675 """ 676 index = self.event_prefix % self.emap_index 677 while self.eid_trans.has_key(str(index)): 678 self.emap_index += 1 679 index = self.event_prefix % self.emap_index 680 self.emap_index += 1 681 return index
682
683 - def find_next_object_gramps_id(self):
684 """ 685 Return the next available GRAMPS' ID for a MediaObject object based 686 off the media object ID prefix. 687 """ 688 index = self.mediaobject_prefix % self.omap_index 689 while self.oid_trans.has_key(str(index)): 690 self.omap_index += 1 691 index = self.mediaobject_prefix % self.omap_index 692 self.omap_index += 1 693 return index
694
695 - def find_next_source_gramps_id(self):
696 """ 697 Return the next available GRAMPS' ID for a Source object based off the 698 source ID prefix. 699 """ 700 index = self.source_prefix % self.smap_index 701 while self.sid_trans.has_key(str(index)): 702 self.smap_index += 1 703 index = self.source_prefix % self.smap_index 704 self.smap_index += 1 705 return index
706
707 - def find_next_family_gramps_id(self):
708 """ 709 Return the next available GRAMPS' ID for a Family object based off the 710 family ID prefix. 711 """ 712 index = self.family_prefix % self.fmap_index 713 while self.fid_trans.has_key(str(index)): 714 self.fmap_index += 1 715 index = self.family_prefix % self.fmap_index 716 self.fmap_index += 1 717 return index
718
720 """ 721 Return the next available GRAMPS' ID for a Respository object based 722 off the repository ID prefix. 723 """ 724 index = self.repository_prefix % self.rmap_index 725 while self.rid_trans.has_key(str(index)): 726 self.rmap_index += 1 727 index = self.repository_prefix % self.rmap_index 728 self.rmap_index += 1 729 return index
730
731 - def find_next_note_gramps_id(self):
732 """ 733 Return the next available GRAMPS' ID for a Note object based off the 734 note ID prefix. 735 """ 736 index = self.note_prefix % self.nmap_index 737 while self.nid_trans.has_key(str(index)): 738 self.nmap_index += 1 739 index = self.note_prefix % self.nmap_index 740 self.nmap_index += 1 741 return index
742
743 - def get_from_handle(self, handle, class_type, data_map):
744 data = data_map.get(str(handle)) 745 if data: 746 newobj = class_type() 747 newobj.unserialize(data) 748 return newobj 749 return None
750
751 - def get_person_from_handle(self, handle):
752 """ 753 Find a Person in the database from the passed gramps' ID. 754 755 If no such Person exists, None is returned. 756 """ 757 return self.get_from_handle(handle, Person, self.person_map)
758
759 - def get_source_from_handle(self, handle):
760 """ 761 Find a Source in the database from the passed gramps' ID. 762 763 If no such Source exists, None is returned. 764 """ 765 return self.get_from_handle(handle, Source, self.source_map)
766
767 - def get_object_from_handle(self, handle):
768 """ 769 Find an Object in the database from the passed gramps' ID. 770 771 If no such Object exists, None is returned. 772 """ 773 return self.get_from_handle(handle, MediaObject, self.media_map)
774
775 - def get_place_from_handle(self, handle):
776 """ 777 Find a Place in the database from the passed gramps' ID. 778 779 If no such Place exists, None is returned. 780 """ 781 return self.get_from_handle(handle, Place, self.place_map)
782
783 - def get_event_from_handle(self, handle):
784 """ 785 Find a Event in the database from the passed gramps' ID. 786 787 If no such Event exists, None is returned. 788 """ 789 return self.get_from_handle(handle, Event, self.event_map)
790
791 - def get_family_from_handle(self, handle):
792 """ 793 Find a Family in the database from the passed gramps' ID. 794 795 If no such Family exists, None is returned. 796 """ 797 return self.get_from_handle(handle, Family, self.family_map)
798
799 - def get_repository_from_handle(self, handle):
800 """ 801 Find a Repository in the database from the passed gramps' ID. 802 803 If no such Repository exists, None is returned. 804 """ 805 return self.get_from_handle(handle, Repository, self.repository_map)
806
807 - def get_note_from_handle(self, handle):
808 """ 809 Find a Note in the database from the passed gramps' ID. 810 811 If no such Note exists, None is returned. 812 """ 813 return self.get_from_handle(handle, Note, self.note_map)
814
815 - def find_from_handle(self, handle, transaction, class_type, dmap, 816 add_func):
817 """ 818 Find a object of class_type in the database from the passed handle. 819 820 If no object exists, a new object is added to the database. 821 822 @return: Returns a tuple, first the object, second a bool which is True 823 if the object is new 824 @rtype: tuple 825 """ 826 obj = class_type() 827 handle = str(handle) 828 new = True 829 if dmap.has_key(handle): 830 obj.unserialize(dmap.get(handle)) 831 #references create object with id None before object is really made 832 if obj.gramps_id is not None: 833 new = False 834 else: 835 obj.set_handle(handle) 836 add_func(obj, transaction) 837 return obj, new
838
839 - def __check_from_handle(self, handle, transaction, class_type, dmap, 840 add_func, set_gid=True):
841 handle = str(handle) 842 if not dmap.has_key(handle): 843 obj = class_type() 844 obj.set_handle(handle) 845 add_func(obj, transaction, set_gid=set_gid)
846
847 - def find_person_from_handle(self, handle, transaction):
848 """ 849 Find a Person in the database from the passed handle. 850 851 If no such Person exists, a new Person is added to the database. 852 853 @return: Returns a tuple, first the object, second a bool which is True 854 if the object is new 855 @rtype: tuple 856 """ 857 return self.find_from_handle(handle, transaction, Person, 858 self.person_map, self.add_person)
859
860 - def find_source_from_handle(self, handle, transaction):
861 """ 862 Find a Source in the database from the passed handle. 863 864 If no such Source exists, a new Source is added to the database. 865 866 @return: Returns a tuple, first the object, second a bool which is True 867 if the object is new 868 @rtype: tuple 869 """ 870 return self.find_from_handle(handle, transaction, Source, 871 self.source_map, self.add_source)
872
873 - def find_event_from_handle(self, handle, transaction):
874 """ 875 Find a Event in the database from the passed handle. 876 877 If no such Event exists, a new Event is added to the database. 878 879 @return: Returns a tuple, first the object, second a bool which is True 880 if the object is new 881 @rtype: tuple 882 """ 883 return self.find_from_handle(handle, transaction, Event, 884 self.event_map, self.add_event)
885
886 - def find_object_from_handle(self, handle, transaction):
887 """ 888 Find a MediaObject in the database from the passed handle. 889 890 If no such MediaObject exists, a new Object is added to the database. 891 892 @return: Returns a tuple, first the object, second a bool which is True 893 if the object is new 894 @rtype: tuple 895 """ 896 return self.find_from_handle(handle, transaction, MediaObject, 897 self.media_map, self.add_object)
898
899 - def find_place_from_handle(self, handle, transaction):
900 """ 901 Find a Place in the database from the passed handle. 902 903 If no such Place exists, a new Place is added to the database. 904 905 @return: Returns a tuple, first the object, second a bool which is True 906 if the object is new 907 @rtype: tuple 908 """ 909 return self.find_from_handle(handle, transaction, Place, 910 self.place_map, self.add_place)
911
912 - def find_family_from_handle(self, handle, transaction):
913 """ 914 Find a Family in the database from the passed handle. 915 916 If no such Family exists, a new Family is added to the database. 917 918 @return: Returns a tuple, first the object, second a bool which is True 919 if the object is new 920 @rtype: tuple 921 """ 922 return self.find_from_handle(handle, transaction, Family, 923 self.family_map, self.add_family)
924
925 - def find_repository_from_handle(self, handle, transaction):
926 """ 927 Find a Repository in the database from the passed handle. 928 929 If no such Repository exists, a new Repository is added to the database. 930 931 @return: Returns a tuple, first the object, second a bool which is True 932 if the object is new 933 @rtype: tuple 934 """ 935 return self.find_from_handle(handle, transaction, Repository, 936 self.repository_map, self.add_repository)
937
938 - def find_note_from_handle(self, handle, transaction):
939 """ 940 Find a Note in the database from the passed handle. 941 942 If no such Note exists, a new Note is added to the database. 943 944 @return: Returns a tuple, first the object, second a bool which is True 945 if the object is new 946 @rtype: tuple 947 """ 948 return self.find_from_handle(handle, transaction, Note, 949 self.note_map, self.add_note)
950
951 - def check_person_from_handle(self, handle, transaction, set_gid=True):
952 """ 953 Check whether a Person with the passed handle exists in the database. 954 955 If no such Person exists, a new Person is added to the database. 956 If set_gid then a new gramps_id is created, if not, None is used. 957 """ 958 self.__check_from_handle(handle, transaction, Person, 959 self.person_map, self.add_person, 960 set_gid = set_gid)
961
962 - def check_source_from_handle(self, handle, transaction, set_gid=True):
963 """ 964 Check whether a Source with the passed handle exists in the database. 965 966 If no such Source exists, a new Source is added to the database. 967 If set_gid then a new gramps_id is created, if not, None is used. 968 """ 969 self.__check_from_handle(handle, transaction, Source, 970 self.source_map, self.add_source, 971 set_gid=set_gid)
972
973 - def check_event_from_handle(self, handle, transaction, set_gid=True):
974 """ 975 Check whether an Event with the passed handle exists in the database. 976 977 If no such Event exists, a new Event is added to the database. 978 If set_gid then a new gramps_id is created, if not, None is used. 979 """ 980 self.__check_from_handle(handle, transaction, Event, 981 self.event_map, self.add_event, 982 set_gid=set_gid)
983
984 - def check_object_from_handle(self, handle, transaction, set_gid=True):
985 """ 986 Check whether a MediaObject with the passed handle exists in the 987 database. 988 989 If no such MediaObject exists, a new Object is added to the database. 990 If set_gid then a new gramps_id is created, if not, None is used. 991 """ 992 993 self.__check_from_handle(handle, transaction, MediaObject, 994 self.media_map, self.add_object, 995 set_gid=set_gid)
996
997 - def check_place_from_handle(self, handle, transaction, set_gid=True):
998 """ 999 Check whether a Place with the passed handle exists in the database. 1000 1001 If no such Place exists, a new Place is added to the database. 1002 If set_gid then a new gramps_id is created, if not, None is used. 1003 """ 1004 self.__check_from_handle(handle, transaction, Place, 1005 self.place_map, self.add_place, 1006 set_gid=set_gid)
1007
1008 - def check_family_from_handle(self, handle, transaction, set_gid=True):
1009 """ 1010 Check whether a Family with the passed handle exists in the database. 1011 1012 If no such Family exists, a new Family is added to the database. 1013 If set_gid then a new gramps_id is created, if not, None is used. 1014 """ 1015 self.__check_from_handle(handle, transaction, Family, 1016 self.family_map, self.add_family, 1017 set_gid=set_gid)
1018
1019 - def check_repository_from_handle(self, handle, transaction, set_gid=True):
1020 """ 1021 Check whether a Repository with the passed handle exists in the 1022 database. 1023 1024 If no such Repository exists, a new Repository is added to the database. 1025 If set_gid then a new gramps_id is created, if not, None is used. 1026 """ 1027 self.__check_from_handle(handle, transaction, Repository, 1028 self.repository_map, self.add_repository, 1029 set_gid=set_gid)
1030
1031 - def check_note_from_handle(self, handle, transaction, set_gid=True):
1032 """ 1033 Check whether a Note with the passed handle exists in the database. 1034 1035 If no such Note exists, a new Note is added to the database. 1036 If set_gid then a new gramps_id is created, if not, None is used. 1037 """ 1038 self.__check_from_handle(handle, transaction, Note, 1039 self.note_map, self.add_note, 1040 set_gid=set_gid)
1041
1042 - def get_person_from_gramps_id(self, val):
1043 """ 1044 Find a Person in the database from the passed GRAMPS ID. 1045 1046 If no such Person exists, None is returned. 1047 Needs to be overridden by the derrived class. 1048 """ 1049 raise NotImplementedError
1050
1051 - def get_family_from_gramps_id(self, val):
1052 """ 1053 Find a Family in the database from the passed GRAMPS ID. 1054 1055 If no such Family exists, None is returned. 1056 Need to be overridden by the derrived class. 1057 """ 1058 raise NotImplementedError
1059
1060 - def get_event_from_gramps_id(self, val):
1061 """ 1062 Find an Event in the database from the passed GRAMPS ID. 1063 1064 If no such Event exists, None is returned. 1065 Needs to be overridden by the derrived class. 1066 """ 1067 raise NotImplementedError
1068
1069 - def get_place_from_gramps_id(self, val):
1070 """ 1071 Find a Place in the database from the passed gramps' ID. 1072 1073 If no such Place exists, None is returned. 1074 Needs to be overridden by the derrived class. 1075 """ 1076 raise NotImplementedError
1077
1078 - def get_source_from_gramps_id(self, val):
1079 """ 1080 Find a Source in the database from the passed gramps' ID. 1081 1082 If no such Source exists, None is returned. 1083 Needs to be overridden by the derrived class. 1084 """ 1085 raise NotImplementedError
1086
1087 - def get_object_from_gramps_id(self, val):
1088 """ 1089 Find a MediaObject in the database from the passed gramps' ID. 1090 1091 If no such MediaObject exists, None is returned. 1092 Needs to be overridden by the derrived class. 1093 """ 1094 raise NotImplementedError
1095
1096 - def get_repository_from_gramps_id(self, val):
1097 """ 1098 Find a Repository in the database from the passed gramps' ID. 1099 1100 If no such Repository exists, None is returned. 1101 Needs to be overridden by the derrived class. 1102 """ 1103 raise NotImplementedError
1104
1105 - def get_note_from_gramps_id(self, val):
1106 """ 1107 Find a Note in the database from the passed gramps' ID. 1108 1109 If no such Note exists, None is returned. 1110 Needs to be overridden by the derrived class. 1111 """ 1112 raise NotImplementedError
1113
1114 - def __add_object(self, obj, transaction, find_next_func, commit_func):
1115 if find_next_func and not obj.gramps_id: 1116 obj.gramps_id = find_next_func() 1117 if not obj.handle: 1118 obj.handle = self.create_id() 1119 commit_func(obj, transaction) 1120 if obj.__class__.__name__ == 'Person': 1121 self.genderStats.count_person (obj) 1122 return obj.handle
1123
1124 - def add_person(self, person, transaction, set_gid=True):
1125 """ 1126 Add a Person to the database, assigning internal IDs if they have 1127 not already been defined. 1128 1129 If not set_gid, then gramps_id is not set. 1130 """ 1131 if set_gid: 1132 return self.__add_object(person, transaction, 1133 self.find_next_person_gramps_id, 1134 self.commit_person) 1135 else: 1136 return self.__add_object(person, transaction, 1137 None, 1138 self.commit_person)
1139
1140 - def add_family(self, family, transaction, set_gid=True):
1141 """ 1142 Add a Family to the database, assigning internal IDs if they have 1143 not already been defined. 1144 1145 If not set_gid, then gramps_id is not set. 1146 """ 1147 if set_gid: 1148 return self.__add_object(family, transaction, 1149 self.find_next_family_gramps_id, 1150 self.commit_family) 1151 else: 1152 return self.__add_object(family, transaction, 1153 None, 1154 self.commit_family)
1155
1156 - def add_source(self, source, transaction, set_gid=True):
1157 """ 1158 Add a Source to the database, assigning internal IDs if they have 1159 not already been defined. 1160 1161 If not set_gid, then gramps_id is not set. 1162 """ 1163 if set_gid: 1164 return self.__add_object(source, transaction, 1165 self.find_next_source_gramps_id, 1166 self.commit_source) 1167 else : 1168 return self.__add_object(source, transaction, 1169 None, 1170 self.commit_source)
1171
1172 - def add_event(self, event, transaction, set_gid=True):
1173 """ 1174 Add an Event to the database, assigning internal IDs if they have 1175 not already been defined. 1176 1177 If not set_gid, then gramps_id is not set. 1178 """ 1179 if set_gid: 1180 return self.__add_object(event, transaction, 1181 self.find_next_event_gramps_id, 1182 self.commit_event) 1183 else: 1184 return self.__add_object(event, transaction, 1185 None, 1186 self.commit_event)
1187
1188 - def add_person_event(self, event, transaction):
1189 """ 1190 Add an Event to the database, assigning internal IDs if they have 1191 not already been defined. 1192 """ 1193 if event.type.is_custom(): 1194 self.individual_event_names.add(str(event.type)) 1195 return self.add_event(event, transaction)
1196
1197 - def add_family_event(self, event, transaction):
1198 """ 1199 Add an Event to the database, assigning internal IDs if they have 1200 not already been defined. 1201 """ 1202 if event.type.is_custom(): 1203 self.family_event_names.add(str(event.type)) 1204 return self.add_event(event, transaction)
1205
1206 - def add_place(self, place, transaction, set_gid=True):
1207 """ 1208 Add a Place to the database, assigning internal IDs if they have 1209 not already been defined. 1210 1211 If not set_gid, then gramps_id is not set. 1212 """ 1213 if set_gid: 1214 return self.__add_object(place, transaction, 1215 self.find_next_place_gramps_id, 1216 self.commit_place) 1217 else: 1218 return self.__add_object(place, transaction, 1219 None, 1220 self.commit_place)
1221
1222 - def add_object(self, obj, transaction, set_gid=True):
1223 """ 1224 Add a MediaObject to the database, assigning internal IDs if they have 1225 not already been defined. 1226 1227 If not set_gid, then gramps_id is not set. 1228 """ 1229 if set_gid: 1230 return self.__add_object(obj, transaction, 1231 self.find_next_object_gramps_id, 1232 self.commit_media_object) 1233 else: 1234 return self.__add_object(obj, transaction, 1235 None, 1236 self.commit_media_object)
1237
1238 - def add_repository(self, obj, transaction, set_gid=True):
1239 """ 1240 Add a Repository to the database, assigning internal IDs if they have 1241 not already been defined. 1242 1243 If not set_gid, then gramps_id is not set. 1244 """ 1245 if set_gid: 1246 return self.__add_object(obj, transaction, 1247 self.find_next_repository_gramps_id, 1248 self.commit_repository) 1249 else: 1250 return self.__add_object(obj, transaction, 1251 None, 1252 self.commit_repository)
1253
1254 - def add_note(self, obj, transaction, set_gid=True):
1255 """ 1256 Add a Note to the database, assigning internal IDs if they have 1257 not already been defined. 1258 1259 If not set_gid, then gramps_id is not set. 1260 """ 1261 if set_gid: 1262 return self.__add_object(obj, transaction, 1263 self.find_next_note_gramps_id, 1264 self.commit_note) 1265 else: 1266 return self.__add_object(obj, transaction, 1267 None, 1268 self.commit_note)
1269
1270 - def get_name_group_mapping(self, name):
1271 """ 1272 Return the default grouping name for a surname. 1273 """ 1274 return unicode(self.name_group.get(str(name), name))
1275
1276 - def get_name_group_keys(self):
1277 """ 1278 Return the defined names that have been assigned to a default grouping. 1279 """ 1280 return [unicode(k) for k in self.name_group.keys()]
1281
1282 - def has_name_group_key(self, name):
1283 """ 1284 Return if a key exists in the name_group table. 1285 """ 1286 return self.name_group.has_key(str(name))
1287
1288 - def set_name_group_mapping(self, name, group):
1289 """ 1290 Set the default grouping name for a surname. 1291 1292 Needs to be overridden in the derived class. 1293 """ 1294 raise NotImplementedError
1295
1296 - def get_number_of_people(self):
1297 """ 1298 Return the number of people currently in the database. 1299 """ 1300 if self.db_is_open: 1301 return len(self.person_map) 1302 else: 1303 return 0
1304
1305 - def get_number_of_families(self):
1306 """ 1307 Return the number of families currently in the database. 1308 """ 1309 return len(self.family_map)
1310
1311 - def get_number_of_events(self):
1312 """ 1313 Return the number of events currently in the database. 1314 """ 1315 return len(self.event_map)
1316
1317 - def get_number_of_places(self):
1318 """ 1319 Return the number of places currently in the database. 1320 """ 1321 return len(self.place_map)
1322
1323 - def get_number_of_sources(self):
1324 """ 1325 Return the number of sources currently in the database. 1326 """ 1327 return len(self.source_map)
1328
1330 """ 1331 Return the number of media objects currently in the database. 1332 """ 1333 return len(self.media_map)
1334
1335 - def get_number_of_repositories(self):
1336 """ 1337 Return the number of source repositories currently in the database. 1338 """ 1339 return len(self.repository_map)
1340
1341 - def get_number_of_notes(self):
1342 """ 1343 Return the number of notes currently in the database. 1344 """ 1345 return len(self.note_map)
1346
1347 - def all_handles(self, table):
1348 return table.keys()
1349
1350 - def get_person_handles(self, sort_handles=True):
1351 """ 1352 Return a list of database handles, one handle for each Person in 1353 the database. 1354 1355 If sort_handles is True, the list is sorted by surnames. 1356 """ 1357 if self.db_is_open: 1358 if sort_handles: 1359 slist = [] 1360 cursor = self.get_person_cursor() 1361 data = cursor.first() 1362 while data: 1363 slist.append((data[1][3][3], data[0])) 1364 data = cursor.next() 1365 cursor.close() 1366 slist.sort() 1367 return map(lambda x: x[1], slist) 1368 else: 1369 return self.all_handles(self.person_map) 1370 return []
1371
1372 - def get_place_handles(self, sort_handles=True):
1373 """ 1374 Return a list of database handles, one handle for each Place in 1375 the database. 1376 1377 If sort_handles is True, the list is sorted by Place title. 1378 """ 1379 if self.db_is_open: 1380 if sort_handles: 1381 slist = [] 1382 cursor = self.get_place_cursor() 1383 data = cursor.first() 1384 while data: 1385 slist.append((data[1][2], data[0])) 1386 data = cursor.next() 1387 cursor.close() 1388 slist.sort() 1389 val = map(lambda x: x[1], slist) 1390 return val 1391 else: 1392 return self.all_handles(self.place_map) 1393 return []
1394
1395 - def get_source_handles(self, sort_handles=True):
1396 """ 1397 Return a list of database handles, one handle for each Source in 1398 the database. 1399 1400 If sort_handles is True, the list is sorted by Source title. 1401 """ 1402 if self.db_is_open: 1403 handle_list = self.all_handles(self.source_map) 1404 if sort_handles: 1405 handle_list.sort(self.__sortbysource) 1406 return handle_list 1407 return []
1408
1409 - def get_media_object_handles(self, sort_handles=True):
1410 """ 1411 Return a list of database handles, one handle for each MediaObject in 1412 the database. 1413 1414 If sort_handles is True, the list is sorted by title. 1415 """ 1416 if self.db_is_open: 1417 handle_list = self.all_handles(self.media_map) 1418 if sort_handles: 1419 handle_list.sort(self.__sortbymedia) 1420 return handle_list 1421 return []
1422
1423 - def get_event_handles(self):
1424 """ 1425 Return a list of database handles, one handle for each Event in the 1426 database. 1427 """ 1428 if self.db_is_open: 1429 return self.all_handles(self.event_map) 1430 return []
1431
1432 - def get_family_handles(self):
1433 """ 1434 Return a list of database handles, one handle for each Family in 1435 the database. 1436 """ 1437 if self.db_is_open: 1438 return self.all_handles(self.family_map) 1439 return []
1440
1441 - def get_repository_handles(self):
1442 """ 1443 Return a list of database handles, one handle for each Repository in 1444 the database. 1445 """ 1446 if self.db_is_open: 1447 return self.all_handles(self.repository_map) 1448 return []
1449
1450 - def get_note_handles(self):
1451 """ 1452 Return a list of database handles, one handle for each Note in the 1453 database. 1454 """ 1455 if self.db_is_open: 1456 return self.all_handles(self.note_map) 1457 return []
1458
1459 - def get_gramps_ids(self, obj_key):
1460 key2table = { 1461 PERSON_KEY: self.id_trans, 1462 FAMILY_KEY: self.fid_trans, 1463 SOURCE_KEY: self.sid_trans, 1464 EVENT_KEY: self.eid_trans, 1465 MEDIA_KEY: self.oid_trans, 1466 PLACE_KEY: self.pid_trans, 1467 REPOSITORY_KEY: self.rid_trans, 1468 NOTE_KEY: self.nid_trans, 1469 } 1470 1471 table = key2table[obj_key] 1472 return table.keys()
1473
1474 - def has_gramps_id(self, obj_key, gramps_id):
1475 key2table = { 1476 PERSON_KEY: self.id_trans, 1477 FAMILY_KEY: self.fid_trans, 1478 SOURCE_KEY: self.sid_trans, 1479 EVENT_KEY: self.eid_trans, 1480 MEDIA_KEY: self.oid_trans, 1481 PLACE_KEY: self.pid_trans, 1482 REPOSITORY_KEY: self.rid_trans, 1483 NOTE_KEY: self.nid_trans, 1484 } 1485 1486 table = key2table[obj_key] 1487 return table.has_key(str(gramps_id))
1488
1489 - def find_initial_person(self):
1490 person = self.get_default_person() 1491 if not person: 1492 the_ids = self.get_gramps_ids(PERSON_KEY) 1493 if the_ids: 1494 person = self.get_person_from_gramps_id(min(the_ids)) 1495 return person
1496
1497 - def _validated_id_prefix(self, val, default):
1498 if val: 1499 try: 1500 junk = val % 1 1501 prefix_var = val # use the prefix as is because it works fine 1502 except: 1503 try: 1504 val = val + "%d" 1505 junk = val % 1 1506 prefix_var = val # format string was missing 1507 except: 1508 prefix_var = default+"%04d" # use default 1509 else: 1510 prefix_var = default+"%04d" 1511 return prefix_var
1512
1513 - def set_person_id_prefix(self, val):
1514 """ 1515 Set the naming template for GRAMPS Person ID values. 1516 1517 The string is expected to be in the form of a simple text string, or 1518 in a format that contains a C/Python style format string using %d, 1519 such as I%d or I%04d. 1520 """ 1521 self.person_prefix = self._validated_id_prefix(val, "I")
1522
1523 - def set_source_id_prefix(self, val):
1524 """ 1525 Set the naming template for GRAMPS Source ID values. 1526 1527 The string is expected to be in the form of a simple text string, or 1528 in a format that contains a C/Python style format string using %d, 1529 such as S%d or S%04d. 1530 """ 1531 self.source_prefix = self._validated_id_prefix(val, "S")
1532
1533 - def set_object_id_prefix(self, val):
1534 """ 1535 Set the naming template for GRAMPS MediaObject ID values. 1536 1537 The string is expected to be in the form of a simple text string, or 1538 in a format that contains a C/Python style format string using %d, 1539 such as O%d or O%04d. 1540 """ 1541 self.mediaobject_prefix = self._validated_id_prefix(val, "O")
1542
1543 - def set_place_id_prefix(self, val):
1544 """ 1545 Set the naming template for GRAMPS Place ID values. 1546 1547 The string is expected to be in the form of a simple text string, or 1548 in a format that contains a C/Python style format string using %d, 1549 such as P%d or P%04d. 1550 """ 1551 self.place_prefix = self._validated_id_prefix(val, "P")
1552
1553 - def set_family_id_prefix(self, val):
1554 """ 1555 Set the naming template for GRAMPS Family ID values. The string is 1556 expected to be in the form of a simple text string, or in a format 1557 that contains a C/Python style format string using %d, such as F%d 1558 or F%04d. 1559 """ 1560 self.family_prefix = self._validated_id_prefix(val, "F")
1561
1562 - def set_event_id_prefix(self, val):
1563 """ 1564 Set the naming template for GRAMPS Event ID values. 1565 1566 The string is expected to be in the form of a simple text string, or 1567 in a format that contains a C/Python style format string using %d, 1568 such as E%d or E%04d. 1569 """ 1570 self.event_prefix = self._validated_id_prefix(val, "E")
1571
1572 - def set_repository_id_prefix(self, val):
1573 """ 1574 Set the naming template for GRAMPS Repository ID values. 1575 1576 The string is expected to be in the form of a simple text string, or 1577 in a format that contains a C/Python style format string using %d, 1578 such as R%d or R%04d. 1579 """ 1580 self.repository_prefix = self._validated_id_prefix(val, "R")
1581
1582 - def set_note_id_prefix(self, val):
1583 """ 1584 Set the naming template for GRAMPS Note ID values. 1585 1586 The string is expected to be in the form of a simple text string, or 1587 in a format that contains a C/Python style format string using %d, 1588 such as N%d or N%04d. 1589 """ 1590 self.note_prefix = self._validated_id_prefix(val, "N")
1591
1592 - def transaction_begin(self, msg="", batch=False, no_magic=False):
1593 """ 1594 Create a new Transaction tied to the current UNDO database. 1595 1596 The transaction has no effect until it is committed using the 1597 transaction_commit function of the this database object. 1598 """ 1599 if self._LOG_ALL: 1600 LOG.debug("%s: Transaction begin '%s'\n" 1601 % (self.__class__.__name__, str(msg))) 1602 if batch: 1603 # A batch transaction does not store the commits 1604 # Aborting the session completely will become impossible. 1605 self.abort_possible = False 1606 self.undo_history_timestamp = time.time() 1607 # Undo is also impossible after batch transaction 1608 self.undoindex = -1 1609 self.translist = [None] * _UNDO_SIZE 1610 return Transaction(msg, self.undodb, batch)
1611
1612 - def transaction_commit(self, transaction, msg):
1613 """ 1614 Commit the transaction to the assocated UNDO database. 1615 """ 1616 if self._LOG_ALL: 1617 LOG.debug("%s: Transaction commit '%s'\n" 1618 % (self.__class__.__name__, str(msg))) 1619 1620 if not len(transaction) or self.readonly: 1621 return 1622 1623 transaction.set_description(msg) 1624 transaction.timestamp = time.time() 1625 self.undoindex += 1 1626 if self.undoindex >= _UNDO_SIZE: 1627 # We overran the undo size. 1628 # Aborting the session completely will become impossible. 1629 self.abort_possible = False 1630 self.undo_history_timestamp = time.time() 1631 self.translist = self.translist[0:-1] + [ transaction ] 1632 else: 1633 self.translist[self.undoindex] = transaction 1634 # Real commit erases all subsequent transactions 1635 # to there's no Redo anymore. 1636 for index in range(self.undoindex+1, _UNDO_SIZE): 1637 self.translist[index] = None 1638 1639 person_add = self.do_commit(transaction.person_add, self.person_map) 1640 family_add = self.do_commit(transaction.family_add, self.family_map) 1641 source_add = self.do_commit(transaction.source_add, self.source_map) 1642 place_add = self.do_commit(transaction.place_add, self.place_map) 1643 media_add = self.do_commit(transaction.media_add, self.media_map) 1644 event_add = self.do_commit(transaction.event_add, self.event_map) 1645 repository_add = self.do_commit(transaction.repository_add, 1646 self.repository_map) 1647 1648 note_add = self.do_commit(transaction.note_add, self.note_map) 1649 person_upd = self.do_commit(transaction.person_update, self.person_map) 1650 family_upd = self.do_commit(transaction.family_update, self.family_map) 1651 source_upd = self.do_commit(transaction.source_update, self.source_map) 1652 place_upd = self.do_commit(transaction.place_update, self.place_map) 1653 media_upd = self.do_commit(transaction.media_update, self.media_map) 1654 event_upd = self.do_commit(transaction.event_update, self.event_map) 1655 repository_upd = self.do_commit(transaction.repository_update, 1656 self.repository_map) 1657 note_upd = self.do_commit(transaction.note_update, self.note_map) 1658 1659 self.__do_emit('person', person_add, person_upd, transaction.person_del) 1660 self.__do_emit('family', family_add, family_upd, transaction.family_del) 1661 self.__do_emit('event', event_add, event_upd, transaction.event_del) 1662 self.__do_emit('source', source_add, source_upd, transaction.source_del) 1663 self.__do_emit('place', place_add, place_upd, transaction.place_del) 1664 self.__do_emit('media', media_add, media_upd, transaction.media_del) 1665 self.__do_emit('repository', repository_add, repository_upd, 1666 transaction.repository_del) 1667 self.__do_emit('note', note_add, note_upd, transaction.note_del) 1668 1669 self.__do_del(transaction.person_del, self.del_person) 1670 self.__do_del(transaction.family_del, self.del_family) 1671 self.__do_del(transaction.place_del, self.del_place) 1672 self.__do_del(transaction.source_del, self.del_source) 1673 self.__do_del(transaction.event_del, self.del_event) 1674 self.__do_del(transaction.media_del, self.del_media) 1675 self.__do_del(transaction.repository_del, self.del_repository) 1676 self.__do_del(transaction.note_del, self.del_note) 1677 1678 if self.undo_callback: 1679 self.undo_callback(_("_Undo %s") % transaction.get_description()) 1680 if self.redo_callback: 1681 self.redo_callback(None) 1682 if self.undo_history_callback: 1683 self.undo_history_callback()
1684
1685 - def __do_emit(self, objtype, add_list, upd_list, del_list):
1686 if add_list: 1687 self.emit(objtype + '-add', (add_list, )) 1688 if upd_list: 1689 self.emit(objtype + '-update', (upd_list, )) 1690 if del_list: 1691 self.emit(objtype + '-delete', (del_list, ))
1692
1693 - def __do_del(self, del_list, func):
1694 for handle in del_list: 1695 func(handle) 1696 return del_list
1697
1698 - def do_commit(self, add_list, db_map):
1699 retlist = [] 1700 for (handle, data) in add_list: 1701 db_map[handle] = data 1702 retlist.append(str(handle)) 1703 return retlist
1704
1705 - def undo_available(self):
1706 """ 1707 Return boolean of whether or not there's a possibility of undo. 1708 """ 1709 if self.undoindex == -1 or self.readonly: 1710 return False 1711 return True
1712
1713 - def redo_available(self):
1714 """ 1715 Return boolean of whether or not there's a possibility of redo. 1716 """ 1717 if self.undoindex >= _UNDO_SIZE or self.readonly: 1718 return False 1719 1720 if self.translist[self.undoindex+1] == None: 1721 return False 1722 1723 return True
1724
1725 - def undo(self, update_history=True):
1726 """ 1727 Access the last committed transaction, and revert the data to the 1728 state before the transaction was committed. 1729 """ 1730 if not self.undo_available(): 1731 return False 1732 1733 transaction = self.translist[self.undoindex] 1734 1735 mapbase = (self.person_map, self.family_map, self.source_map, 1736 self.event_map, self.media_map, self.place_map, 1737 self.repository_map, {}, self.note_map) 1738 1739 self.undoindex -= 1 1740 subitems = transaction.get_recnos() 1741 subitems.reverse() 1742 for record_id in subitems: 1743 (key, handle, old_data, new_data) = transaction.get_record(record_id) 1744 if key == REFERENCE_KEY: 1745 self.undo_reference(old_data, handle) 1746 else: 1747 self.undo_data(old_data, handle, mapbase[key], _SIGBASE[key]) 1748 1749 if self.undo_callback: 1750 if self.undo_available(): 1751 new_transaction = self.translist[self.undoindex] 1752 self.undo_callback(_("_Undo %s") 1753 % new_transaction.get_description()) 1754 else: 1755 self.undo_callback(None) 1756 1757 if self.redo_callback: 1758 if self. redo_available(): 1759 self.redo_callback(_("_Redo %s") 1760 % transaction.get_description()) 1761 else: 1762 self.redo_callback(None) 1763 1764 if update_history and self.undo_history_callback: 1765 self.undo_history_callback() 1766 return True
1767
1768 - def redo(self, update_history=True):
1769 """ 1770 Accesse the last undone transaction, and revert the data to the state 1771 before the transaction was undone. 1772 """ 1773 1774 if not self.redo_available(): 1775 return False 1776 1777 self.undoindex += 1 1778 transaction = self.translist[self.undoindex] 1779 mapbase = (self.person_map, self.family_map, self.source_map, 1780 self.event_map, self.media_map, self.place_map, 1781 self.repository_map, {}, self.note_map) 1782 1783 subitems = transaction.get_recnos() 1784 for record_id in subitems: 1785 (key, handle, old_data, new_data) = transaction.get_record(record_id) 1786 if key == REFERENCE_KEY: 1787 self.undo_reference(new_data, handle) 1788 else: 1789 self.undo_data(new_data, handle, mapbase[key], _SIGBASE[key]) 1790 1791 if self.undo_callback: 1792 if self.undo_available(): 1793 self.undo_callback(_("_Undo %s") 1794 % transaction.get_description()) 1795 else: 1796 self.undo_callback(None) 1797 1798 if self.redo_callback: 1799 if self.redo_available(): 1800 new_transaction = self.translist[self.undoindex+1] 1801 self.redo_callback(_("_Redo %s") 1802 % new_transaction.get_description()) 1803 else: 1804 self.redo_callback(None) 1805 1806 if update_history and self.undo_history_callback: 1807 self.undo_history_callback() 1808 return True
1809
1810 - def undo_reference(self, data, handle):
1811 pass
1812
1813 - def undo_data(self, data, handle, db_map, signal_root):
1814 if data == None: 1815 self.emit(signal_root + '-delete', ([handle], )) 1816 del db_map[handle] 1817 else: 1818 if db_map.has_key(handle): 1819 signal = signal_root + '-update' 1820 else: 1821 signal = signal_root + '-add' 1822 db_map[handle] = data 1823 self.emit(signal, ([handle], ))
1824
1825 - def set_undo_callback(self, callback):
1826 """ 1827 Define the callback function that is called whenever an undo operation 1828 is executed. 1829 1830 The callback function receives a single argument that is a text string 1831 that defines the operation. 1832 """ 1833 self.undo_callback = callback
1834
1835 - def set_redo_callback(self, callback):
1836 """ 1837 Define the callback function that is called whenever an redo operation 1838 is executed. 1839 1840 The callback function receives a single argument that is a text string 1841 that defines the operation. 1842 """ 1843 self.redo_callback = callback
1844
1845 - def get_surname_list(self):
1846 """ 1847 Return the list of locale-sorted surnames contained in the database. 1848 """ 1849 return self.surname_list
1850
1851 - def build_surname_list(self):
1852 """ 1853 Build the list of locale-sorted surnames contained in the database. 1854 1855 The function must be overridden in the derived class. 1856 """ 1857 raise NotImplementedError
1858
1859 - def sort_surname_list(self):
1860 vals = [(locale.strxfrm(item), item) for item in self.surname_list] 1861 vals.sort() 1862 self.surname_list = [item[1] for item in vals]
1863
1864 - def add_to_surname_list(self, person, batch_transaction):
1865 if batch_transaction: 1866 return 1867 name = unicode(person.get_primary_name().get_surname()) 1868 if name not in self.surname_list: 1869 self.surname_list.append(name) 1870 self.sort_surname_list()
1871
1872 - def remove_from_surname_list(self, person):
1873 """ 1874 Check whether there are persons with the same surname left in 1875 the database. 1876 1877 If not then we need to remove the name from the list. 1878 The function must be overridden in the derived class. 1879 """ 1880 raise NotImplementedError
1881
1882 - def get_bookmarks(self):
1883 """Return the list of Person handles in the bookmarks.""" 1884 return self.bookmarks
1885
1886 - def get_family_bookmarks(self):
1887 """Return the list of Person handles in the bookmarks.""" 1888 return self.family_bookmarks
1889
1890 - def get_event_bookmarks(self):
1891 """Return the list of Person handles in the bookmarks.""" 1892 return self.event_bookmarks
1893
1894 - def get_place_bookmarks(self):
1895 """Return the list of Person handles in the bookmarks.""" 1896 return self.place_bookmarks
1897
1898 - def get_source_bookmarks(self):
1899 """Return the list of Person handles in the bookmarks.""" 1900 return self.source_bookmarks
1901
1902 - def get_media_bookmarks(self):
1903 """Return the list of Person handles in the bookmarks.""" 1904 return self.media_bookmarks
1905
1906 - def get_repo_bookmarks(self):
1907 """Return the list of Person handles in the bookmarks.""" 1908 return self.repo_bookmarks
1909
1910 - def get_note_bookmarks(self):
1911 """Return the list of Note handles in the bookmarks.""" 1912 return self.note_bookmarks
1913
1914 - def set_researcher(self, owner):
1915 """Set the information about the owner of the database.""" 1916 self.owner.set_from(owner)
1917
1918 - def get_researcher(self):
1919 """ 1920 Return the Researcher instance, providing information about the owner 1921 of the database. 1922 """ 1923 return self.owner
1924
1925 - def set_default_person_handle(self, handle):
1926 """Set the default Person to the passed instance.""" 1927 if (self.metadata != None) and (not self.readonly): 1928 self.metadata['default'] = str(handle)
1929
1930 - def get_default_person(self):
1931 """Return the default Person of the database.""" 1932 person = self.get_person_from_handle(self.get_default_handle()) 1933 if person: 1934 return person 1935 elif (self.metadata != None) and (not self.readonly): 1936 self.metadata['default'] = None 1937 return None
1938
1939 - def get_default_handle(self):
1940 """Return the default Person of the database.""" 1941 if self.metadata != None: 1942 return self.metadata.get('default') 1943 return None
1944
1945 - def get_save_path(self):
1946 """Return the save path of the file, or "" if one does not exist.""" 1947 return self.path
1948
1949 - def set_save_path(self, path):
1950 """Set the save path for the database.""" 1951 self.path = path
1952
1953 - def get_person_event_types(self):
1954 """ 1955 Return a list of all Event types assocated with Person instances in 1956 the database. 1957 """ 1958 return list(self.individual_event_names)
1959
1960 - def get_person_attribute_types(self):
1961 """ 1962 Return a list of all Attribute types assocated with Person instances 1963 in the database. 1964 """ 1965 return list(self.individual_attributes)
1966
1967 - def get_family_attribute_types(self):
1968 """ 1969 Return a list of all Attribute types assocated with Family instances 1970 in the database. 1971 """ 1972 return list(self.family_attributes)
1973
1974 - def get_family_event_types(self):
1975 """ 1976 Return a list of all Event types assocated with Family instances in 1977 the database. 1978 """ 1979 return list(self.family_event_names)
1980
1981 - def get_marker_types(self):
1982 """ 1983 Return a list of all marker types available in the database. 1984 """ 1985 return list(self.marker_names)
1986
1987 - def get_media_attribute_types(self):
1988 """ 1989 Return a list of all Attribute types assocated with Media and MediaRef 1990 instances in the database. 1991 """ 1992 return list(self.media_attributes)
1993
1994 - def get_family_relation_types(self):
1995 """ 1996 Return a list of all relationship types assocated with Family 1997 instances in the database. 1998 """ 1999 return list(self.family_rel_types)
2000
2001 - def get_child_reference_types(self):
2002 """ 2003 Return a list of all child reference types assocated with Family 2004 instances in the database. 2005 """ 2006 return list(self.child_ref_types)
2007
2008 - def get_event_roles(self):
2009 """ 2010 Return a list of all custom event role names assocated with Event 2011 instances in the database. 2012 """ 2013 return list(self.event_role_names)
2014
2015 - def get_name_types(self):
2016 """ 2017 Return a list of all custom names types assocated with Person 2018 instances in the database. 2019 """ 2020 return list(self.name_types)
2021
2022 - def get_repository_types(self):
2023 """ 2024 Return a list of all custom repository types assocated with Repository 2025 instances in the database. 2026 """ 2027 return list(self.repository_types)
2028
2029 - def get_note_types(self):
2030 """ 2031 Return a list of all custom note types assocated with Note instances 2032 in the database. 2033 """ 2034 return list(self.note_types)
2035
2036 - def get_source_media_types(self):
2037 """ 2038 Return a list of all custom source media types assocated with Source 2039 instances in the database. 2040 """ 2041 return list(self.source_media_types)
2042
2043 - def get_url_types(self):
2044 """ 2045 Return a list of all custom names types assocated with Url instances 2046 in the database. 2047 """ 2048 return list(self.url_types)
2049
2050 - def remove_person(self, handle, transaction):
2051 """ 2052 Remove the Person specified by the database handle from the database, 2053 preserving the change in the passed transaction. 2054 2055 This method must be overridden in the derived class. 2056 """ 2057 2058 if self.readonly or not handle: 2059 return 2060 self.delete_primary_from_reference_map(handle, transaction) 2061 person = self.get_person_from_handle(handle) 2062 self.genderStats.uncount_person (person) 2063 self.remove_from_surname_list(person) 2064 if transaction.batch: 2065 self.del_person(handle) 2066 else: 2067 transaction.add(PERSON_KEY, handle, person.serialize(), None) 2068 transaction.person_del.append(str(handle))
2069
2070 - def get_del_func(self, key):
2071 key2del = { 2072 PERSON_KEY: self.del_person, 2073 FAMILY_KEY: self.del_family, 2074 SOURCE_KEY: self.del_source, 2075 EVENT_KEY: self.del_event, 2076 MEDIA_KEY: self.del_media, 2077 PLACE_KEY: self.del_place, 2078 REPOSITORY_KEY: self.del_repository, 2079 NOTE_KEY: self.del_note, 2080 } 2081 return key2del[key]
2082
2083 - def do_remove_object(self, handle, trans, dmap, key, del_list):
2084 if self.readonly or not handle: 2085 return 2086 2087 handle = str(handle) 2088 self.delete_primary_from_reference_map(handle, trans) 2089 if trans.batch: 2090 del_func = self.get_del_func(key) 2091 del_func(handle) 2092 else: 2093 old_data = dmap.get(handle) 2094 trans.add(key, handle, old_data, None) 2095 del_list.append(handle)
2096
2097 - def remove_source(self, handle, transaction):
2098 """ 2099 Remove the Source specified by the database handle from the 2100 database, preserving the change in the passed transaction. 2101 2102 This method must be overridden in the derived class. 2103 """ 2104 self.do_remove_object(handle, transaction, self.source_map, 2105 SOURCE_KEY, transaction.source_del)
2106
2107 - def remove_event(self, handle, transaction):
2108 """ 2109 Remove the Event specified by the database handle from the 2110 database, preserving the change in the passed transaction. 2111 2112 This method must be overridden in the derived class. 2113 """ 2114 self.do_remove_object(handle, transaction, self.event_map, 2115 EVENT_KEY, transaction.event_del)
2116
2117 - def remove_object(self, handle, transaction):
2118 """ 2119 Remove the MediaObjectPerson specified by the database handle from the 2120 database, preserving the change in the passed transaction. 2121 2122 This method must be overridden in the derived class. 2123 """ 2124 self.do_remove_object(handle, transaction, self.media_map, 2125 MEDIA_KEY, transaction.media_del)
2126
2127 - def remove_place(self, handle, transaction):
2128 """ 2129 Remove the Place specified by the database handle from the 2130 database, preserving the change in the passed transaction. 2131 2132 This method must be overridden in the derived class. 2133 """ 2134 self.do_remove_object(handle, transaction, self.place_map, 2135 PLACE_KEY, transaction.place_del)
2136
2137 - def remove_family(self, handle, transaction):
2138 """ 2139 Remove the Family specified by the database handle from the 2140 database, preserving the change in the passed transaction. 2141 2142 This method must be overridden in the derived class. 2143 """ 2144 self.do_remove_object(handle, transaction, self.family_map, 2145 FAMILY_KEY, transaction.family_del)
2146
2147 - def remove_repository(self, handle, transaction):
2148 """ 2149 Remove the Repository specified by the database handle from the 2150 database, preserving the change in the passed transaction. 2151 2152 This method must be overridden in the derived class. 2153 """ 2154 self.do_remove_object(handle, transaction, self.repository_map, 2155 REPOSITORY_KEY, transaction.repository_del)
2156
2157 - def remove_note(self, handle, transaction):
2158 """ 2159 Remove the Note specified by the database handle from the 2160 database, preserving the change in the passed transaction. 2161 2162 This method must be overridden in the derived class. 2163 """ 2164 self.do_remove_object(handle, transaction, self.note_map, 2165 NOTE_KEY, transaction.note_del)
2166
2167 - def get_raw_person_data(self, handle):
2168 return self.person_map.get(str(handle))
2169
2170 - def get_raw_family_data(self, handle):
2171 return self.family_map.get(str(handle))
2172
2173 - def get_raw_object_data(self, handle):
2174 return self.media_map.get(str(handle))
2175
2176 - def get_raw_place_data(self, handle):
2177 return self.place_map.get(str(handle))
2178
2179 - def get_raw_event_data(self, handle):
2180 return self.event_map.get(str(handle))
2181
2182 - def get_raw_source_data(self, handle):
2183 return self.source_map.get(str(handle))
2184
2185 - def get_raw_repository_data(self, handle):
2186 return self.repository_map.get(str(handle))
2187
2188 - def get_raw_note_data(self, handle):
2189 return self.note_map.get(str(handle))
2190
2191 - def has_person_handle(self, handle):
2192 """ 2193 Return True if the handle exists in the current Person database. 2194 """ 2195 return self.person_map.has_key(str(handle))
2196
2197 - def has_event_handle(self, handle):
2198 """ 2199 Return True if the handle exists in the current Event database. 2200 """ 2201 return self.event_map.has_key(str(handle))
2202
2203 - def has_source_handle(self, handle):
2204 """ 2205 Return True if the handle exists in the current Source database. 2206 """ 2207 return self.source_map.has_key(str(handle))
2208
2209 - def has_place_handle(self, handle):
2210 """ 2211 Return True if the handle exists in the current Place database. 2212 """ 2213 return self.place_map.has_key(str(handle))
2214
2215 - def has_family_handle(self, handle):
2216 """ 2217 Return True if the handle exists in the current Family database. 2218 """ 2219 return self.family_map.has_key(str(handle))
2220
2221 - def has_object_handle(self, handle):
2222 """ 2223 Return True if the handle exists in the current MediaObjectdatabase. 2224 """ 2225 return self.media_map.has_key(str(handle))
2226
2227 - def has_repository_handle(self, handle):
2228 """ 2229 Return True if the handle exists in the current Repository database. 2230 """ 2231 return self.repository_map.has_key(str(handle))
2232
2233 - def has_note_handle(self, handle):
2234 """ 2235 Return True if the handle exists in the current Note database. 2236 """ 2237 return self.note_map.has_key(str(handle))
2238
2239 - def __sortbyplace(self, first, second):
2240 return locale.strcoll(self.place_map.get(str(first))[2], 2241 self.place_map.get(str(second))[2])
2242
2243 - def __sortbysource(self, first, second):
2244 source1 = unicode(self.source_map[str(first)][2]) 2245 source2 = unicode(self.source_map[str(second)][2]) 2246 return locale.strcoll(source1, source2)
2247
2248 - def __sortbymedia(self, first, second):
2249 media1 = self.media_map[str(first)][4] 2250 media2 = self.media_map[str(second)][4] 2251 return locale.strcoll(media1, media2)
2252
2253 - def set_mediapath(self, path):
2254 """Set the default media path for database, path should be utf-8.""" 2255 if (self.metadata != None) and (not self.readonly): 2256 self.metadata['mediapath'] = path
2257
2258 - def get_mediapath(self):
2259 """Return the default media path of the database.""" 2260 if self.metadata != None: 2261 return self.metadata.get('mediapath', None) 2262 return None
2263
2264 - def set_column_order(self, col_list, name):
2265 if (self.metadata != None) and (not self.readonly): 2266 self.metadata[name] = col_list
2267
2268 - def set_person_column_order(self, col_list):
2269 """ 2270 Store the Person display common information in the database's metadata. 2271 """ 2272 self.set_column_order(col_list, PERSON_COL_KEY)
2273
2274 - def set_family_list_column_order(self, col_list):
2275 """ 2276 Store the Person display common information in the database's metadata. 2277 """ 2278 self.set_column_order(col_list, FAMILY_COL_KEY)
2279
2280 - def set_child_column_order(self, col_list):
2281 """ 2282 Store the Person display common information in the database's metadata. 2283 """ 2284 self.set_column_order(col_list, CHILD_COL_KEY)
2285
2286 - def set_place_column_order(self, col_list):
2287 """ 2288 Store the Place display common information in the database's metadata. 2289 """ 2290 self.set_column_order(col_list, PLACE_COL_KEY)
2291
2292 - def set_source_column_order(self, col_list):
2293 """ 2294 Store the Source display common information in the database's metadata. 2295 """ 2296 self.set_column_order(col_list, SOURCE_COL_KEY)
2297
2298 - def set_media_column_order(self, col_list):
2299 """ 2300 Store the Media display common information in the database's metadata. 2301 """ 2302 self.set_column_order(col_list, MEDIA_COL_KEY)
2303
2304 - def set_event_column_order(self, col_list):
2305 """ 2306 Store the Event display common information in the database's metadata. 2307 """ 2308 self.set_column_order(col_list, EVENT_COL_KEY)
2309
2310 - def set_repository_column_order(self, col_list):
2311 """ 2312 Store the Repository display common information in the database's 2313 metadata. 2314 """ 2315 self.set_column_order(col_list, REPOSITORY_COL_KEY)
2316
2317 - def set_note_column_order(self, col_list):
2318 """ 2319 Store the Note display common information in the database's metadata. 2320 """ 2321 self.set_column_order(col_list, NOTE_COL_KEY)
2322
2323 - def __get_column_order(self, name, default):
2324 if self.metadata == None: 2325 return default 2326 else: 2327 cols = self.metadata.get(name, default) 2328 if len(cols) != len(default): 2329 return cols + default[len(cols):] 2330 else: 2331 return cols
2332
2333 - def get_person_column_order(self):
2334 """ 2335 Return the Person display common information stored in the database's 2336 metadata. 2337 """ 2338 default = [(1, 1, 100), (1, 2, 100), (1, 3, 150), (0, 4, 150), 2339 (1, 5, 150), (0, 6, 150), (0, 7, 100), (0, 8, 100), 2340 ] 2341 return self.__get_column_order(PERSON_COL_KEY, default)
2342
2343 - def __get_columns(self, key, default):
2344 values = self.__get_column_order(key, default) 2345 new = [] 2346 for val in values: 2347 if len(val) == 2: 2348 for x in default: 2349 if val[1] == x[1]: 2350 new.append((val[0], val[1], x[2])) 2351 break 2352 else: 2353 new.append(val) 2354 return new
2355
2356 - def get_family_list_column_order(self):
2357 """ 2358 Return the Person display common information stored in the database's 2359 metadata. 2360 """ 2361 default = [(1, 0, 75), (1, 1, 200), (1, 2, 200), (1, 3, 100), 2362 (0, 4, 100)] 2363 return self.__get_columns(FAMILY_COL_KEY, default)
2364
2365 - def get_child_column_order(self):
2366 """ 2367 Return the Person display common information stored in the database's 2368 metadata. 2369 """ 2370 default = [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), 2371 (0, 6), (0, 7)] 2372 return self.__get_column_order(CHILD_COL_KEY, default)
2373
2374 - def get_place_column_order(self):
2375 """ 2376 Return the Place display common information stored in thedatabase's 2377 metadata. 2378 """ 2379 default = [(1, 0, 250), (1, 1, 75), (1, 11, 100), (0, 3, 100), 2380 (1, 4, 100, ), (0, 5, 150), (1, 6, 150), (0, 7, 150), 2381 (0, 8, 150), (0, 9, 150), (0, 10, 150),(0,2,100)] 2382 return self.__get_columns(PLACE_COL_KEY, default)
2383
2384 - def get_source_column_order(self):
2385 """ 2386 Return the Source display common information stored in the database's 2387 metadata. 2388 """ 2389 default = [(1, 0, 200), (1, 1, 75), (1, 2, 150), (0, 3, 100), 2390 (1, 4, 150), (0, 5, 100)] 2391 return self.__get_columns(SOURCE_COL_KEY, default)
2392
2393 - def get_media_column_order(self):
2394 """ 2395 Return the MediaObject display common information stored in the 2396 database's metadata. 2397 """ 2398 default = [(1, 0, 200, ), (1, 1, 75), (1, 2, 100), (1, 3, 200), 2399 (1, 5, 150), (0, 4, 150)] 2400 return self.__get_columns(MEDIA_COL_KEY, default)
2401
2402 - def get_event_column_order(self):
2403 """ 2404 Return the Event display common information stored in the database's 2405 metadata. 2406 """ 2407 default = [(1, 0, 200), (1, 1, 75), (1, 2, 100), (1, 3, 150), 2408 (1, 4, 200), (0, 5, 100)] 2409 return self.__get_columns(EVENT_COL_KEY, default)
2410
2411 - def get_repository_column_order(self):
2412 """ 2413 Return the Repository display common information stored in the 2414 database's metadata. 2415 """ 2416 default = [(1, 0, 200), (1, 1, 75), (0, 5, 100), (0, 6, 100), 2417 (1, 2, 100), (1, 3, 250), (1, 4, 100), (0, 7, 100), 2418 (0, 8, 100), (0, 9, 100), (0, 10, 100), (0, 12, 100)] 2419 return self.__get_columns(REPOSITORY_COL_KEY, default)
2420
2421 - def get_note_column_order(self):
2422 """ 2423 Return the Note display common information stored in the database's 2424 metadata. 2425 """ 2426 default = [(1, 0, 350), (1, 1, 75), (1, 2, 100), (1, 3, 100)] 2427 return self.__get_columns(NOTE_COL_KEY, default)
2428
2429 - def delete_primary_from_reference_map(self, handle, transaction):
2430 """ 2431 Called each time an object is removed from the database. 2432 2433 This can be used by subclasses to update any additional index tables 2434 that might need to be changed. 2435 """ 2436 pass
2437
2438 - def update_reference_map(self, obj, transaction):
2439 """ 2440 Called each time an object is writen to the database. 2441 2442 This can be used by subclasses to update any additional index tables 2443 that might need to be changed. 2444 """ 2445 pass
2446
2447 - def reindex_reference_map(self, callback):
2448 """ 2449 Reindex all primary records in the database. 2450 """ 2451 pass
2452 2530
2531 - def report_bm_change(self):
2532 """ 2533 Add 1 to the number of bookmark changes during this session. 2534 """ 2535 self._bm_changes += 1
2536
2537 - def db_has_bm_changes(self):
2538 """ 2539 Return whethere there were bookmark changes during the session. 2540 """ 2541 return self._bm_changes > 0
2542
2543 -class Transaction:
2544 """ 2545 Define a group of database commits that define a single logical operation. 2546 """
2547 - def __init__(self, msg, db, batch=False, no_magic=False):
2548 """ 2549 Create a new transaction. 2550 2551 A Transaction instance should not be created directly, but by the 2552 GrampsDbBase class or classes derived from GrampsDbBase. The db 2553 parameter is a list-like interface that stores the commit data. This 2554 could be a simple list, or a RECNO-style database object. 2555 2556 The batch parameter is set to True for large transactions. For such 2557 transactions, the list of changes is not maintained, and no undo 2558 is possible. 2559 2560 The no_magic parameter is ignored for non-batch transactions, and 2561 is also of no importance for DB backends other than BSD DB. For 2562 the BSDDB, when this paramter is set to True, some secondary 2563 indices will be removed at the beginning and then rebuilt at 2564 the end of such transaction (only if it is batch). 2565 """ 2566 self.db = db 2567 self.first = None 2568 self.last = None 2569 self.batch = batch 2570 self.no_magic = no_magic 2571 self.length = 0 2572 self.timestamp = 0 2573 2574 self.person_add = [] 2575 self.person_del = [] 2576 self.person_update = [] 2577 2578 self.family_add = [] 2579 self.family_del = [] 2580 self.family_update = [] 2581 2582 self.source_add = [] 2583 self.source_del = [] 2584 self.source_update = [] 2585 2586 self.event_add = [] 2587 self.event_del = [] 2588 self.event_update = [] 2589 2590 self.media_add = [] 2591 self.media_del = [] 2592 self.media_update = [] 2593 2594 self.place_add = [] 2595 self.place_del = [] 2596 self.place_update = [] 2597 2598 self.repository_add = [] 2599 self.repository_del = [] 2600 self.repository_update = [] 2601 2602 self.note_add = [] 2603 self.note_del = [] 2604 self.note_update = []
2605
2606 - def get_description(self):
2607 """ 2608 Return the text string that describes the logical operation performed 2609 by the Transaction. 2610 """ 2611 return self.msg
2612
2613 - def set_description(self, msg):
2614 """ 2615 Set the text string that describes the logical operation performed by 2616 the Transaction. 2617 """ 2618 self.msg = msg
2619
2620 - def add(self, obj_type, handle, old_data, new_data):
2621 """ 2622 Add a commit operation to the Transaction. 2623 2624 The obj_type is a constant that indicates what type of PrimaryObject 2625 is being added. The handle is the object's database handle, and the 2626 data is the tuple returned by the object's serialize method. 2627 """ 2628 self.last = self.db.append( 2629 cPickle.dumps((obj_type, handle, old_data, new_data), 1)) 2630 if self.first == None: 2631 self.first = self.last
2632
2633 - def get_recnos(self):
2634 """ 2635 Return a list of record numbers associated with the transaction. 2636 2637 While the list is an arbitrary index of integers, it can be used 2638 to indicate record numbers for a database. 2639 """ 2640 return range (self.first, self.last+1)
2641
2642 - def get_record(self, recno):
2643 """ 2644 Return a tuple representing the PrimaryObject type, database handle 2645 for the PrimaryObject, and a tuple representing the data created by 2646 the object's serialize method. 2647 """ 2648 return cPickle.loads(self.db[recno])
2649
2650 - def __len__(self):
2651 """ 2652 Return the number of commits associated with the Transaction. 2653 """ 2654 if self.last and self.first: 2655 return self.last - self.first + 1 2656 return 0
2657