GUID Equivalent in Zope?
Hi All, We need to be able to add a system-generated unique key string to a record entered into an RDBMS via a Zope application. The same database is also accessed by an ASP application which uses GUIDs for this function: - - Is there something similar to a GUID generator in Zope? - If so, would it be practical to actually generate this string in the same format as MS GUIDs (I know they look horrible, but an trying to keep equivalence between the ASP-powered functions and the Zope-powered functions)? FWIW, the Zope application is on Win32, so perhaps we could get Windows to generate us a GUID? Thanks in anticipation for any input! -- Regards, PhilK Email: phil@xfr.co.uk / Voicemail & Facsimile: 07092 070518 "the symbols of the divine show up in our world initially at the trash stratum." Philip K Dick
http://www.zope.org/Members/andym/GUID "Ever had to generate unique ids? If you are running on Windows one simple answer is the GUID generation system from Microsoft" Philip Kilner wrote:
Hi All,
We need to be able to add a system-generated unique key string to a record entered into an RDBMS via a Zope application. The same database is also accessed by an ASP application which uses GUIDs for this function: -
- Is there something similar to a GUID generator in Zope?
- If so, would it be practical to actually generate this string in the same format as MS GUIDs (I know they look horrible, but an trying to keep equivalence between the ASP-powered functions and the Zope-powered functions)?
FWIW, the Zope application is on Win32, so perhaps we could get Windows to generate us a GUID?
Thanks in anticipation for any input!
------------------------------------------------------------------------
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
-- Andy McKay http://www.agmweb.ca
Hi Andy, Andy McKay wrote:
http://www.zope.org/Members/andym/GUID
"Ever had to generate unique ids? If you are running on Windows one simple answer is the GUID generation system from Microsoft"
You're a star! <confession> I hadn't even looked on Zope.org - just seemed to "low level" for there to be a solution on a plate! </confession> -- Regards, PhilK Email: phil@xfr.co.uk / Voicemail & Facsimile: 07092 070518 "the symbols of the divine show up in our world initially at the trash stratum." Philip K Dick
<confession>
I hadn't even looked on Zope.org - just seemed to "low level" for there to be a solution on a plate!
</confession>
Almost everything is on Zope.org or equivalent site. The answer is of course always google: http://www.google.ca/search?q=GUID+Zope+Windows :) -- Andy McKay http://www.agmweb.ca
Hi Andy, Andy McKay wrote:
<confession>
I hadn't even looked on Zope.org - just seemed to "low level" for there to be a solution on a plate!
</confession>
Almost everything is on Zope.org or equivalent site. The answer is of course always google:
http://www.google.ca/search?q=GUID+Zope+Windows
:)
I never tire of telling others this - but overlooked my own excellent advice!!! ;-) -- Regards, PhilK Email: phil@xfr.co.uk / Voicemail & Facsimile: 07092 070518 "the symbols of the divine show up in our world initially at the trash stratum." Philip K Dick
Philip Kilner wrote:
Andy McKay wrote:
http://www.zope.org/Members/andym/GUID "Ever had to generate unique ids? If you are running on Windows one simple answer is the GUID generation system from Microsoft" You're a star!
There's also a none Windows GUID Python class at ActiveState (that might be useful if you ever consider other plattforms): http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/163604 which I have made a Zope GUIDGenerator for: #!/usr/bin/python # A globally unique identifier made up of time and ip # Copyright (C) 2002 Dr. Conan C. Albrecht <conan_albrecht@byu.edu> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import random import socket import time from Persistence import Persistent class GUID: """\ A globally-unique identifier made up of time and ip and the server (client) port or 4 random digits: 36 characters wide A globally unique identifier that combines ip, time, and random bits. Since the time is listed first, you can sort records by guid. You can also extract the time and ip if needed. GUIDs make wonderful database keys. They require no access to the database (to get the max index number), they are extremely unique, and they sort automatically by time. GUIDs prevent key clashes when merging two databases together, combining data, or generating keys in distributed systems. """ rand = random.Random() ip = '' hexip = '' lastguid = '' def __init__(self, guid=None, port=None): """\ Constructor. Use no args if you want the guid generated (this is the normal method) or send a string-typed guid to generate it from the string """ if guid == None: ip = '' hexip = '' try: ip = socket.gethostbyname(socket.gethostname()) except (socket.gaierror): # if we don't have an ip, default to someting in the 10.x.x.x private range ip = '10' for i in range(3): ip += '.' + str(self.rand.randrange(1, 254)) hexip = ''.join(["%04x" % long(i) for i in ip.split('.')]) # leave space for ip v6 (65K in each sub) ip_tuple=tuple(ip.split('.')) if port is None or port>65535: port=self.rand.randrange(1, 65535) hexport=("%04x" % port) guid = self.__class__.lastguid while guid == self.__class__.lastguid: timestamp = long(time.time() * 1000) hextimestamp = "%016x" % timestamp guid = hextimestamp + hexip + hexport self.__class__.lastguid=self.__guid=guid elif type(guid) == type(self): self.update(guid) else: self.__guid=guid def parse_guid(self, guid): if type(guid)!=StringType or len(guid)!=36: raise "InvalidGUID", "'%s' isn't a valid GUID." % str(guid) hextimestamp=guid[0:16] hexip=guid[16:32] hexport=guid[32:36] timestamp=long(guid[0:16], 16) ip_tuple=() for sub in (hexip[0:4], hexip[4:8], hexip[8:12], hexip[12:16]): sub=eval('0x'+sub, {}, {}) ip_tuple=ip_tuple+(sub,) ip='.'.join(ip_tuple) port=eval('0x'+hexport, {}, {}) return timestamp, ip, ip_tuple, port,hextimestamp, hexip, hexport def update(self, guid): if type(guid) != type(self): raise "InvalidGUID", "The value passed was not of the type GUID." self.__guid=self.getGUID() def __str__(self): """Returns the string value of this guid""" return self.__guid def __repr__(self): """Returns the string value of this guid""" return "<GUID %s />" % self.__guid def getGUID(self): return self.__guid def getHexTimestamp(self): return self.__guid[0:16] def getHexIP(self): return self.__guid[16:32] def getHexPort(self): return self.__guid[-4:] def getTimestamp(self): """Extracts the time portion out of the guid and returns the number of milliseconds since the epoch""" return long(self.__guid[0:16], 16) def getIP(self): """Extracts the ip portion out of the guid and returns it as a string like 10.10.10.10""" # there's probably a more elegant way to do this ip = '' index = 16 while index < 32: if ip != '': ip += "." ip += str(int(self.__guid[index: index + 4], 16)) index += 4 return ip def getIP_tuple(self): ip_tuple=() for sub in (self.__guid[16:20], self.__guid[20:24], self.__guid[24:28], self.__guid[28:32]): ip_tuple=ip_tuple+(int(sub, 16),) return ip_tuple def getPort(self): """Extracts the random bits from the guid. I have no idea how this would be useful, but I've included it for completeness""" return int(self.__guid[-4:], 16) class GUIDGenerator(Persistent): """\ This GUIDGenerator does provide a unique ID. If two threads collide this the same GUID new none equal GUIDs will be created and returned. GUIDs are based on time and ip-adress and a random number. The only time as GUID could be same is if the machines have the same ip-address and/or on machine has two server instances on different ports (this needs to be fixed). """ _value=None def createGUID(self): self._value=GUID() return self._value def _p_resolveConflict(self, oldState, savedState, newState): if savedState['_value'] == oldState['_value'] or savedState['_value'] == newState['_value']: oldState['_value'] = GUID() return oldState # XXX What if _p_resolveConflict _thinks_ it resolved the # conflict, but did something wrong? if __name__ == "__main__": # just print out a for testing guid = GUID() print "GUID: " + str(guid) millis = guid.time() print "Time: " + str(millis) + " millis (" + time.asctime(time.gmtime(millis / 1000)) + " UTC)" print "IP: " + guid.ip() print "Rand: " + str(guid.random()) -- Johan Carlsson Tel: + 46 8 31 24 94 Colliberty Mob: + 46 70 558 25 24 Torsgatan 72 Email: johanc@easypublisher.com SE-113 37 STOCKHOLM
participants (3)
-
Andy McKay -
Johan Carlsson -
Philip Kilner