[Assorted-commits] SF.net SVN: assorted:[895] simple-zdb/trunk
Brought to you by:
yangzhang
From: <yan...@us...> - 2008-07-18 01:36:46
|
Revision: 895 http://assorted.svn.sourceforge.net/assorted/?rev=895&view=rev Author: yangzhang Date: 2008-07-18 01:36:55 +0000 (Fri, 18 Jul 2008) Log Message: ----------- added basic consistency checking; added load/dump for entire db using sections (delimiting parents); fixed to use multi-value props Modified Paths: -------------- simple-zdb/trunk/README simple-zdb/trunk/src/zdb.py Modified: simple-zdb/trunk/README =================================================================== --- simple-zdb/trunk/README 2008-07-18 00:39:19 UTC (rev 894) +++ simple-zdb/trunk/README 2008-07-18 01:36:55 UTC (rev 895) @@ -14,5 +14,4 @@ Bugs: -- handle multiple values per property - handle inheritance correctly Modified: simple-zdb/trunk/src/zdb.py =================================================================== --- simple-zdb/trunk/src/zdb.py 2008-07-18 00:39:19 UTC (rev 894) +++ simple-zdb/trunk/src/zdb.py 2008-07-18 01:36:55 UTC (rev 895) @@ -32,42 +32,85 @@ def add( self, name, parents, props ): self.addobj( obj( name, parents, props ) ) def set( self, name, field, value ): - self.name2obj[ name ].props[ field ] = value + self.name2obj[ name ].addprop( field, value ) def rm( self, name ): del self.name2obj[ name ] def dump( self, path ): with file( path, 'w' ) as f: - f.write( 'blah' ) - def load( self, parent, path ): + for parent in sorted( db.name2obj.iterkeys() ): + first = True + for name, o in sorted( db.name2obj.iteritems() ): + if o.parents == [ parent ]: + # header + if first: + print >> f, '===', parent, '===' + print >> f + first = False + print >> f, o.name + for field, values in sorted( o.props.iteritems() ): + for value in values: + if '\n' in value: + print >> f, '%s::' % field + print >> f, value + print >> f, '::' + else: + print >> f, '%s: %s' % ( field, value ) + print >> f + def load( self, path ): + names = set() with file( path ) as f: - for o in parse( f.read(), [parent] ): - self.addobj( o ) + for o in parse( f.read() ): + self.updateobj( o ) + if o.name in names: + raise zdb_exception( 'duplicate names detected in load input' ) + names.add( o ) # API functions def addobj( self, o ): + if o.name in db.name2obj: raise zdb_exception('already exists: ' + o.name) self.name2obj[ o.name ] = o + def updateobj( self, o ): + self.name2obj[ o.name ] = o + def check( self ): + o = None + try: + for name, o in self.name2obj.iteritems(): + assert name == o.name, 'name mismatch' + assert len( o.parents ) == 1 or name == 'concept' and o.parents == [], \ + 'all objs beside concept must have single parent (for now)' + for p in o.parents: + assert p in self.name2obj, 'parent doesnt exist: %s' % p + # TODO make sure there are no cycles in the parent graph and that + # everything terminates at root 'concept' + except AssertionError, ex: + print >> stderr, o.name + raise class obj( object ): 'An object in the ZDB object database' - __slots__ = 'name parents props'.split() - def __eq__( self, other ): - return ( type( self ) == type( other ) and - self.name == other.name and - self.props == other.props and - self.parents == other.parents ) + # __slots__ = 'name parents props'.split() def __init__( self, name, parents, props ): global db self.name = name + assert parents != None and parents != [] self.parents = parents self.props = {} for p in props: self.props[p] = [] - if name in db.name2obj: raise zdb_exception('already exists: ' + name) + def __eq__( self, other ): + return ( type( self ) == type( other ) and + self.name == other.name and + self.props == other.props and + self.parents == other.parents ) + def addprop( self, field, value ): + try: d = self.props[ field ] + except: d = self.props[ field ] = [] + d.append( value ) # # DB files management # -def dbfiles(): return sorted( dbdir.glob('*'), key = dbnum ) -def dbnum(dbpath): return int( x.split('-')[-1] ) +def dbfiles(): return sorted( path( '/' ).glob(dbdir + '*'), key = dbnum ) +def dbnum(dbpath): return int( dbpath.split('-')[-1] ) def loaddb(): global db @@ -82,6 +125,7 @@ dbs = dbfiles() newdb = dbdir + str( dbnum(dbs[-1]) + 1 if len( dbs ) > 0 else 0 ) soft_makedirs( newdb.dirname() ) + db.check() with file(newdb, 'w') as f: dump( ( time(), db ), f ) # @@ -103,7 +147,7 @@ # parser # -def parse( s, parents ): +def parse( s ): line = None counter = free_struct() counter.i = 0 @@ -112,26 +156,32 @@ return f.readline().rstrip() try: f = StringIO(s.strip()) + parents = None while True: - name = readline(f).strip() - if name == '': break - o = obj( name, parents, [] ) - while True: - line = readline(f).strip() - if line == '': break - m = match( '^([^:]+)::$', line ) - if m is not None: - field = m.group(1) - buf = [] - while True: - line = readline(f) - if line == '::': break - buf.append( line ) - value = '\n'.join( buf ).rstrip() - else: - [field, value] = line.split(': ', 1) - o.props[ field ] = value - yield o + line = readline(f).strip() + if line == '': break + if line.startswith( '=== ' ) and line.endswith( ' ===' ): + parents = [ line.lstrip('=').rstrip('=').strip() ] + assert '' == readline(f) # read an empty line + continue + else: + o = obj( line, parents, [] ) + while True: + line = readline(f).strip() + if line == '': break + m = match( '^([^:]+)::$', line ) + if m is not None: + field = m.group(1) + buf = [] + while True: + line = readline(f) + if line == '::': break + buf.append( line ) + value = '\n'.join( buf ).rstrip() + else: + [ field, value ] = line.split(': ', 1) + o.addprop( field, value ) + yield o except: print >> stderr, 'line %d: %s' % ( counter.i, line ) raise @@ -153,18 +203,18 @@ :: Michael Jackson -google: emilie +email: mj...@ne... notes:: - loves kids :: ''', [ 'person' ] ) ) expected = [None] * 2 expected[0] = obj( 'Yang Zhang', [ 'person' ], '' ) - expected[0].props[ 'google' ] = 'yaaang' - expected[0].props[ 'notes' ] = '- sucks\n- lame' + expected[0].addprop( 'google', 'yaaang' ) + expected[0].addprop( 'notes', '- sucks\n- lame' ) expected[1] = obj( 'Michael Jackson', [ 'person' ], '' ) - expected[1].props[ 'google' ] = 'emilie' - expected[1].props[ 'notes' ] = '- loves kids' + expected[1].addprop( 'email', 'mj...@ne...' ) + expected[1].addprop( 'notes', '- loves kids' ) self.assertEqual( parsed, expected ) # @@ -180,6 +230,7 @@ while True: stdout.write( '>>> ' ) line = stdin.readline() + if line == '': break words = line.split() if words != []: cmd, params = words[0], words[1:] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |