Commit 38ee97f4 authored by Jeremy Hylton's avatar Jeremy Hylton

Reformat and simplify argument processing.

Add main() function to do argument processing separate from recover().
parent c797432e
......@@ -89,7 +89,6 @@ from ZODB.TimeStamp import TimeStamp
from cPickle import loads
from ZODB.FileStorage import RecordIterator
class EOF(Exception): pass
class ErrorFound(Exception): pass
def error(mess, *args):
......@@ -97,19 +96,17 @@ def error(mess, *args):
def read_transaction_header(file, pos, file_size):
# Read the transaction record
seek=file.seek
read=file.read
seek(pos)
h=read(23)
if len(h) < 23: raise EOF
file.seek(pos)
h = file.read(23)
if len(h) < 23:
raise EOFError
tid, stl, status, ul, dl, el = unpack(">8s8scHHH",h)
if el < 0: el=t32-el
tl=U64(stl)
if status=='c': raise EOF
if status=='c': raise EOFError
if pos+(tl+8) > file_size:
error("bad transaction length at %s", pos)
......@@ -125,17 +122,18 @@ def read_transaction_header(file, pos, file_size):
if status=='u':
# Undone transaction, skip it
seek(tend)
h=read(8)
if h != stl: error('inconsistent transaction length at %s', pos)
pos=tend+8
file.seek(tend)
h = file.read(8)
if h != stl:
error('inconsistent transaction length at %s', pos)
pos = tend + 8
return pos, None
pos=tpos+(23+ul+dl+el)
user=read(ul)
description=read(dl)
pos = tpos+(23+ul+dl+el)
user = file.read(ul)
description = file.read(dl)
if el:
try: e=loads(read(el))
try: e=loads(file.read(el))
except: e={}
else: e={}
......@@ -144,11 +142,11 @@ def read_transaction_header(file, pos, file_size):
pos=tend
# Read the (intentionally redundant) transaction length
seek(pos)
h=read(8)
file.seek(pos)
h = file.read(8)
if h != stl:
error("redundant transaction length check failed at %s", pos)
pos=pos+8
pos += 8
return pos, result
......@@ -175,123 +173,131 @@ def scan(file, pos, file_size):
return pos + s + 8
def iprogress(i):
if i%2: print '.',
else: print (i/2)%10,
if i % 2:
print '.',
else:
print (i/2) % 10,
sys.stdout.flush()
def progress(p):
for i in range(p): iprogress(i)
def recover(argv=sys.argv):
for i in range(p):
iprogress(i)
def main():
try:
opts, (inp, outp) = getopt.getopt(argv[1:], 'fv:pP:')
force = partial = verbose = 0
pack = None
for opt, v in opts:
if opt == '-v': verbose = int(v)
elif opt == '-p': partial=1
elif opt == '-f': force=1
elif opt == '-P': pack=time.time()-float(v)
force = filter(lambda opt: opt[0]=='-f', opts)
partial = filter(lambda opt: opt[0]=='-p', opts)
verbose = filter(lambda opt: opt[0]=='-v', opts)
verbose = verbose and int(verbose[0][1]) or 0
print 'Recovering', inp, 'into', outp
except:
opts, (inp, outp) = getopt.getopt(sys.argv[1:], 'fv:pP:')
except getopt.error:
die()
print __doc__ % argv[0]
force = partial = verbose = 0
pack = None
for opt, v in opts:
if opt == '-v':
verbose = int(v)
elif opt == '-p':
partial = 1
elif opt == '-f':
force = 1
elif opt == '-P':
pack = time.time() - float(v)
recover(inp, outp, verobse, partial, force, pack)
def recover(inp, outp, verbose=0, partial=0, force=0, pack=0):
print 'Recovering', inp, 'into', outp
if os.path.exists(outp) and not force:
die("%s exists" % outp)
file=open(inp, "rb")
seek=file.seek
read=file.read
if read(4) != ZODB.FileStorage.packed_version:
file = open(inp, "rb")
if file.read(4) != ZODB.FileStorage.packed_version:
die("input is not a file storage")
seek(0,2)
file_size=file.tell()
file.seek(0,2)
file_size = file.tell()
ofs=ZODB.FileStorage.FileStorage(outp, create=1)
_ts=None
ok=1
prog1=0
preindex={}; preget=preindex.get # waaaa
undone=0
ofs = ZODB.FileStorage.FileStorage(outp, create=1)
_ts = None
ok = 1
prog1 = 0
preindex = {}
undone = 0
pos=4
pos = 4
while pos:
try:
npos, transaction = read_transaction_header(file, pos, file_size)
except EOF:
except EOFError:
break
except:
print "\n%s: %s\n" % sys.exc_info()[:2]
if not verbose: progress(prog1)
if not verbose:
progress(prog1)
pos = scan(file, pos, file_size)
continue
if transaction is None:
undone = undone + npos - pos
pos=npos
pos = npos
continue
else:
pos=npos
pos = npos
tid=transaction.tid
tid = transaction.tid
if _ts is None:
_ts=TimeStamp(tid)
_ts = TimeStamp(tid)
else:
t=TimeStamp(tid)
t = TimeStamp(tid)
if t <= _ts:
if ok: print ('Time stamps out of order %s, %s' % (_ts, t))
ok=0
_ts=t.laterThan(_ts)
tid=`_ts`
if ok:
print ('Time stamps out of order %s, %s' % (_ts, t))
ok = 0
_ts = t.laterThan(_ts)
tid = `_ts`
else:
_ts = t
if not ok:
print ('Time stamps back in order %s' % (t))
ok=1
ok = 1
if verbose:
print 'begin',
if verbose > 1: print
if verbose > 1:
print
sys.stdout.flush()
ofs.tpc_begin(transaction, tid, transaction.status)
if verbose:
print 'begin', pos, _ts,
if verbose > 1: print
if verbose > 1:
print
sys.stdout.flush()
nrec=0
nrec = 0
try:
for r in transaction:
oid=r.oid
if verbose > 1: print U64(oid), r.version, len(r.data)
pre=preget(oid, None)
s=ofs.store(oid, pre, r.data, r.version, transaction)
preindex[oid]=s
nrec=nrec+1
oid = r.oid
if verbose > 1:
print U64(oid), r.version, len(r.data)
pre = preindex.get(oid)
s = ofs.store(oid, pre, r.data, r.version, transaction)
preindex[oid] = s
nrec += 1
except:
if partial and nrec:
ofs._status='p'
ofs._status = 'p'
ofs.tpc_vote(transaction)
ofs.tpc_finish(transaction)
if verbose: print 'partial'
if verbose:
print 'partial'
else:
ofs.tpc_abort(transaction)
print "\n%s: %s\n" % sys.exc_info()[:2]
if not verbose: progress(prog1)
if not verbose:
progress(prog1)
pos = scan(file, pos, file_size)
else:
ofs.tpc_vote(transaction)
......@@ -321,4 +327,6 @@ def recover(argv=sys.argv):
ofs.close()
if __name__=='__main__': recover()
if __name__ == '__main__':
main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment