Personal wiki notebook (not under development)

Persistent.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import sys
  2. import time
  3. from datetime import datetime
  4. from pytz import utc
  5. class Persistent( object ):
  6. POSTGRESQL_BACKEND = 0
  7. SQLITE_BACKEND = 1
  8. """
  9. A persistent database object with a unique id.
  10. """
  11. def __init__( self, object_id, revision = None ):
  12. self.__object_id = object_id
  13. self.__revision = revision
  14. if not revision:
  15. self.update_revision()
  16. @staticmethod
  17. def sql_load( object_id, revision = None ):
  18. """
  19. Return a SQL string to load an object with the given information from the database. If a
  20. revision is not provided, then the most current version of the given object will be loaded.
  21. @type object_id: unicode
  22. @param object_id: id of object to load
  23. @type revision: unicode or NoneType
  24. @param revision: revision of the object to load (optional)
  25. """
  26. raise NotImplementedError()
  27. @staticmethod
  28. def sql_id_exists( object_id, revision = None ):
  29. """
  30. Return a SQL string to determine whether the given object is present in the database. If a
  31. revision is not provided, then the most current version of the given object will be used.
  32. @type object_id: unicode
  33. @param object_id: id of object to check for existence
  34. @type revision: unicode or NoneType
  35. @param revision: revision of the object to check (optional)
  36. """
  37. raise NotImplementedError()
  38. def sql_exists( self ):
  39. """
  40. Return a SQL string to determine whether the current revision of this object is present in the
  41. database.
  42. """
  43. raise NotImplementedError()
  44. def sql_create( self ):
  45. """
  46. Return a SQL string to save this object to the database for the first time. This should be in
  47. the form of a SQL insert.
  48. """
  49. raise NotImplementedError()
  50. def sql_update( self ):
  51. """
  52. Return a SQL string to save an updated revision of this object to the database. Note that,
  53. because of the retention of old row revisions in the database, this SQL string will usually
  54. be in the form of an insert rather than an update to an existing row.
  55. """
  56. raise NotImplementedError()
  57. def to_dict( self ):
  58. return dict(
  59. object_id = self.__object_id,
  60. revision = self.__revision,
  61. )
  62. def update_revision( self ):
  63. revision = datetime.now( tz = utc )
  64. # as a work around for the low-precision timer on Windows, replace the microseconds with a value
  65. # from a higher-precision timer
  66. if sys.platform.startswith( "win" ):
  67. MICROSECONDS = 1000000
  68. revision = revision.replace( microsecond = int( time.clock() * MICROSECONDS ) % MICROSECONDS )
  69. self.__revision = revision
  70. @staticmethod
  71. def make_cache_key( Object_type, object_id ):
  72. return "%s_%s" % ( object_id, Object_type.__name__ )
  73. object_id = property( lambda self: self.__object_id )
  74. revision = property( lambda self: self.__revision )
  75. cache_key = property( lambda self: Persistent.make_cache_key( type( self ), self.object_id ) )
  76. def quote( value ):
  77. if value is None:
  78. return "null"
  79. if isinstance( value, bool ):
  80. value = value and "t" or "f"
  81. else:
  82. value = unicode( value )
  83. return "'%s'" % value.replace( "'", "''" ).replace( "\\", "\\\\" )
  84. def quote_fuzzy( value ):
  85. if value is None:
  86. return "null"
  87. value = unicode( value )
  88. value = value.replace( "'", "''" ).replace( "\\", "\\\\" )
  89. return "'%" + value + "%'"