[Zodb-checkins] CVS: StandaloneZODB/Tools - timeiter.py:1.1.2.3
Barry Warsaw
barry@wooz.org
Wed, 9 Jan 2002 18:25:50 -0500
Update of /cvs-repository/StandaloneZODB/Tools
In directory cvs.zope.org:/tmp/cvs-serv7169
Modified Files:
Tag: Standby-branch
timeiter.py
Log Message:
Slightly better, but still crufty parameterization of storage
constructor calls. I'm all ears for any better ideas.
=== StandaloneZODB/Tools/timeiter.py 1.1.2.2 => 1.1.2.3 ===
Usage: %(PROGRAM)s [options]
Options:
- -s filename
- --source=filename
- Use database in filename as the source.
-
- -d filename
- --dest=filename
- Use database in filename as the destination.
-
- -S classname
- --stype=classname
- The class name of the source storage, including the full module name.
- Defaults to ZODB.FileStorage.FileStorage.
-
- -D classname
- --dtype=classname
- The class name of the destination storage, including the full module
- name. Defaults to ZODB.FileStorage.FileStorage.
+ -S sourcetype
+ --stype=sourcetype
+ This is the name of a recognized type for the source database. Use -T
+ to print out the known types. Defaults to "file".
+
+ -D desttype
+ --dtype=desttype
+ This is the name of the recognized type for the destination database.
+ Use -T to print out the known types. Defaults to "file".
-o filename
--output=filename
@@ -48,6 +40,9 @@
-p/--profile
Turn on specialized profiling.
+ -T/--storage_types
+ Print all the recognized storage types and exit.
+
-v/--verbose
Turns on verbose output. Multiple -v options increase the verbosity.
@@ -83,18 +78,18 @@
def main():
try:
- opts, args = getopt.getopt(sys.argv[1:], 'hvs:d:o:pm:k:D:S:',
- ['help', 'verbose', 'source=', 'dest=',
- 'output=', 'profile',
- 'max=', 'skip=', 'dtype=', 'stype='])
+ opts, args = getopt.getopt(
+ sys.argv[1:],
+ 'hvo:pm:k:D:S:T',
+ ['help', 'verbose',
+ 'output=', 'profile', 'storage_types',
+ 'max=', 'skip=', 'dtype=', 'stype='])
except getopt.error, msg:
usage(1, msg)
class Options:
- source = None
- dest = None
- stype = 'ZODB.FileStorage.FileStorage'
- dtype = 'ZODB.FileStorage.FileStorage'
+ stype = 'file'
+ dtype = 'file'
verbose = 0
outfile = None
profilep = 0
@@ -108,14 +103,16 @@
usage(0)
elif opt in ('-v', '--verbose'):
options.verbose += 1
- elif opt in ('-s', '--source'):
- options.source = arg
- elif opt in ('-d', '--dest'):
- options.dest = arg
+ elif opt in ('-T', '--storage_types'):
+ keys = STORAGETYPES.keys()
+ keys.sort()
+ for k in keys:
+ print '%s: %s' % (k, STORAGETYPES[k].__doc__)
+ sys.exit(0)
elif opt in ('-S', '--stype'):
- options.stype = arg
+ options.stype = arg.lower()
elif opt in ('-D', '--dtype'):
- options.dtype = arg
+ options.dtype = arg.lower()
elif opt in ('-o', '--output'):
options.outfile = arg
elif opt in ('-p', '--profile'):
@@ -125,11 +122,12 @@
elif opt in ('-k', '--skip'):
options.skiptxn = int(arg)
- if args:
- usage(1)
+ args = list(args)
- if not options.source or not options.dest:
- usage(1, 'Source and destination databases must be provided')
+ if not options.stype in STORAGETYPES.keys():
+ usage(1, 'Source database type must be provided')
+ if not options.dtype in STORAGETYPES.keys():
+ usage(1, 'Destination database type must be provided')
# Open the output file
if options.outfile is None:
@@ -139,47 +137,34 @@
options.outfp = open(options.outfile, 'w')
options.outclosep = 1
- # Import the storage classes
- parts = options.stype.split('.')
- modname = '.'.join(parts[:-1])
- classname = parts[-1]
- __import__(modname)
- Source = getattr(sys.modules[modname], classname)
-
- parts = options.dtype.split('.')
- modname = '.'.join(parts[:-1])
- classname = parts[-1]
- __import__(modname)
- Dest = getattr(sys.modules[modname], classname)
-
if options.verbose > 0:
- print 'Opening source %s on %s...' % (Source.__name__, options.source)
+ print 'Opening source database...'
t0 = time.time()
- # Try to open this storage read-only, but fall back to normal open if
- # that fails
- try:
- srcdb = Source(options.source, read_only=1)
- except TypeError:
- srcdb = Source(options.source)
+ srcdb = STORAGETYPES[options.stype](args)
t1 = time.time()
if options.verbose > 0:
print 'Opening source done in %s seconds' % (t1-t0)
+ # Ugly hack
#srcdb._save_index()
if options.verbose > 0:
- print 'Opening dest %s on %s...' % (Dest.__name__, options.source)
+ print 'Opening destination database...'
t0 = time.time()
- dstdb = Dest(options.dest)
+ # Another ugly hack
+ dstdb = STORAGETYPES[options.dtype](args)
t1 = time.time()
if options.verbose > 0:
print 'Opening destination done in %s seconds' % (t1-t0)
+ if args:
+ usage(1)
+
try:
t0 = time.time()
doit(srcdb, dstdb, options)
t1 = time.time()
if options.verbose > 0:
- print 'Total time:', t1-t0
+ print 'Migration time:', t1-t0
finally:
# Done
srcdb.close()
@@ -279,6 +264,75 @@
marshal.dump(prof.stats, fp)
fp.close()
print >> outfp, largest_pickle, largest_txn_in_size, largest_txn_in_objects
+
+
+
+# This cruft is necessary because otherwise, it's just too dang hard to get
+# the right arguments to the various constructors. If you've got a better
+# idea, I'm all ears!
+def make_fs(args, read_only=0):
+ """Use a read/write FileStorage.
+
+ Requires one argument: the file name of the storage.
+ """
+ if not args:
+ usage(1, 'filename is required')
+ # No return
+ from ZODB.FileStorage import FileStorage
+ filename = args[0]
+ del args[0]
+ return FileStorage(filename, read_only=read_only)
+
+def make_rofs(args):
+ """Use a read-only FileStorage.
+
+ Requires one argument: the file name of the storage.
+ """
+ return make_fs(args, read_only=1)
+
+
+def make_primary(args):
+ """Use a PrimaryStorage.
+
+ Required:
+ filename for the underlying FileStorage
+
+ Optional:
+ private name, defaults to gethostname()
+ port, defaults to RS_PORT
+ """
+ if not args:
+ usage(1, 'filename is required')
+ from ZODB.FileStorage import FileStorage
+ from socket import gethostname
+ from Standby.primary import PrimaryStorage
+ lastarg = 1
+
+ dfs = FileStorage(args[0])
+ if len(args) < 2:
+ name = gethostname()
+ else:
+ name = args[1]
+ lastarg += 1
+ if len(args) < 3:
+ from Standby.config import RS_PORT as port
+ else:
+ port = int(args[2])
+ lastarg += 1
+ del args[:lastarg]
+ return PrimaryStorage(hostname, dfs, port)
+
+
+# This maps case-insensitive names against factory functions. The latter must
+# take a single argument which is the left-over command line, and return a
+# storage object. They should also strip off any arguments they consume from
+# the passed in argument.
+STORAGETYPES = {
+ 'file' : make_fs,
+ 'rofile' : make_rofs,
+ 'primary': make_primary,
+## 'bdb' : make_berkeley,
+ }