transactionalfile.py :  » Blog » Frog » FrogComplete-1.8 » webapps » frog » frog » xmlstorage » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Blog » Frog 
Frog » FrogComplete 1.8 » webapps » frog » frog » xmlstorage » transactionalfile.py
#
#   $Id: transactionalfile.py,v 1.4 2005/05/02 00:07:01 irmen Exp $
#
#   (c) Irmen de Jong.
#   This is open-source software, released under the MIT Software License:
#   http://www.opensource.org/licenses/mit-license.php
#

import os


class TransactionalFile(file):

    """This class attempts to be a file object with transactional
    properties. Writing initially goes to a temporary file instead
    of the target file directly.
    When you're done, you don't close() this file, but you
    commit() or rollback() the file.
    A commit() replaces the old file with the new file
    (using renaming, so should be quite safe and fast).
    When something happens that causes the commit not to be executed,
    such as an error, the file is automatically rollback-ed, and
    the original contents remain untouched.
    NOTE: this is NOT thread-safe!! Don't write the same file from
    within multiple threads, that will not work!"""

    def __init__(self, name, mode='wb', buffering=1):
        if mode not in ('w','wb'):
            raise ValueError("only accepting write mode")
        self.__name=name
        self.__tempname=name+"~"
        file.__init__(self, self.__tempname, mode, buffering)
        
    def __del__(self):
        self.rollback()

    def getName(self):
        return self.__name
    name=property(getName,None,None)
        
    def close(self):
        raise AttributeError("TransactionalFile must be closed using rollback() or commit()")
        # file.close(self)
        
    def rollback(self):
        if not self.closed:
            file.close(self)
            try:
                os.remove(self.__tempname)
            except EnvironmentError:
                pass
        
    def commit(self):
        if not self.closed:
            file.close(self)
            backup=self.__name+"@"
            if os.path.isfile(self.__name):
                try:
                    os.rename(self.__name, backup)
                except EnvironmentError,x:
                    os.remove(self.__tempname)
                    raise
            else:
                backup=None
            try:
                os.rename(self.__tempname, self.__name)
            except EnvironmentError,x:
                os.rename(backup, self.__name)
                raise
            else:
                if backup:
                    os.remove(backup)


def test():
    filename="/tmp/somefile.txt"
    content="The quick brown fox jumps over the lazy dog."
    print "Writing to file",filename
    r=TransactionalFile(filename,"wb")
    r.write(content+'\n')
    print "committing file."
    r.commit()
    print "done."
    print "Writing to file",filename
    r=TransactionalFile(filename,"wb")
    r.write("Scratch that!!!!\n")
    print "rollback file."
    r.rollback()
    print "The file should still contain the original content,"
    print "'%s'." % content

    

if __name__=="__main__":
    test()
 
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.