3 # Dumps database structure into XML to fill SleepyCat's XMLDB
8 use Sleepycat::DbXml 'simple';
12 use Term::ProgressBar;
16 my $xmldb_path = './dbxml'; # -h option for tools
17 my $xmldb_container = 'backuppc.dbxml';
19 my $connect = "DBI:Pg:dbname=backuppc";
21 my $commit_every = 100;
23 my $bar = Term::ProgressBar->new({
31 $bar->message(join(" ",@_));
36 _debug("connecting to $connect\n");
37 my $dbh = DBI->connect($connect,"","") || die $DBI::errstr;
40 # open a container in the db environment
41 my $env = new DbEnv(0);
42 $env->set_cachesize(0, 64 * 1024, 1);
44 $env->open($xmldb_path,
45 Db::DB_INIT_MPOOL|Db::DB_CREATE|Db::DB_INIT_LOCK|Db::DB_INIT_LOG|Db::DB_INIT_TXN);
46 my $theMgr = new XmlManager($env);
48 my $containerTxn = $theMgr->createTransaction();
49 _debug("openContainer $xmldb_container\n");
50 my $container = $theMgr->openContainer($containerTxn, $xmldb_container);
52 $containerTxn->commit();
54 # Get an XmlUpdateContext. Useful from a performance perspective.
55 my $updateContext = $theMgr->createUpdateContext();
57 # myDbEnv and myXmlContainer open with transactions. All subsequent
58 # writes to them must also be performed inside a transaction.
61 my $txn = $theMgr->createTransaction();
64 my $myXMLDoc = $theMgr->createDocument();
68 files.id as unique_id,
72 backups.date as backup_date,
77 backups.size as backup_size
79 join shares on files.shareid = shares.id
80 join hosts on shares.hostid = hosts.id
81 join backups on shares.hostid = backups.hostid
82 and files.backupnum = backups.num
83 and shares.id = backups.shareid
88 my $sth = $dbh->prepare($sql) || die $dbh->errstr();
90 $sth->execute() || die $sth->errstr();
92 _debug( $sth->rows . ' rows returned');
93 $bar->target( $sth->rows );
97 while (my $row = $sth->fetchrow_hashref() ) {
99 my $xml = XMLout( $row );
101 # Set the XmlDocument to the relevant string and then put it
102 # into the container.
103 $myXMLDoc->setContent( "$xml" );
104 $container->putDocument($txn, $myXMLDoc, $updateContext, DbXml::DBXML_GEN_NAME);
106 _debug("skip $i: ".Dumper($row));
110 $next_update = $bar->update( $i ) if ( $i > $next_update );
112 if ($i % $commit_every == 0) {
115 $txn = $theMgr->createTransaction();
116 $bar->message(Dumper($xml));
121 # Normally we would use a try/catch block to trap any exceptions.
122 # In the catch, we should call txn->abort() to avoid leaving the
123 # database in an indeterminate state in the event of an error.
124 # However, this simple example avoids error handling so as to
125 # highlite basic concepts, so that step if omitted here as well.
127 # Commit the writes. This causes the container write operations
128 # to be saved to the container.