From 7f0771a3ed4ec42bd57f246919aba1dd755a207c Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@symas.com>
Date: Tue, 16 Oct 2012 15:28:20 -0700
Subject: [PATCH] Merge mdb_stata into mdb_stat

---
 libraries/libmdb/mdb_stat.c  | 106 +++++++++++++++++++++++++++++------
 libraries/libmdb/mdb_stata.c |  84 ---------------------------
 2 files changed, 90 insertions(+), 100 deletions(-)
 delete mode 100644 libraries/libmdb/mdb_stata.c

diff --git a/libraries/libmdb/mdb_stat.c b/libraries/libmdb/mdb_stat.c
index 97bd8d4467..73891cfcdb 100644
--- a/libraries/libmdb/mdb_stat.c
+++ b/libraries/libmdb/mdb_stat.c
@@ -13,49 +13,123 @@
  */
 #include <stdio.h>
 #include <stdlib.h>
-#include <time.h>
+#include <string.h>
+#include <unistd.h>
 #include "mdb.h"
 
-int main(int argc,char * argv[])
+static void prstat(MDB_stat *ms)
 {
-	int rc;
+	printf("Page size: %u\n", ms->ms_psize);
+	printf("Tree depth: %u\n", ms->ms_depth);
+	printf("Branch pages: %zu\n", ms->ms_branch_pages);
+	printf("Leaf pages: %zu\n", ms->ms_leaf_pages);
+	printf("Overflow pages: %zu\n", ms->ms_overflow_pages);
+	printf("Entries: %zu\n", ms->ms_entries);
+}
+
+static void usage(char *prog)
+{
+	fprintf(stderr, "usage: %s dbpath [-a|-s subdb]\n", prog);
+	exit(EXIT_FAILURE);
+}
+
+int main(int argc, char *argv[])
+{
+	int i, rc;
 	MDB_env *env;
 	MDB_txn *txn;
 	MDB_dbi dbi;
 	MDB_stat mst;
-	char *envname = argv[1];
+	char *prog = argv[0];
+	char *envname;
 	char *subname = NULL;
+	int alldbs = 0;
+
+	if (argc < 2) {
+		usage(prog);
+	}
+
+	/* -a: print stat of main DB and all subDBs
+	 * -s: print stat of only the named subDB
+	 * (default) print stat of only the main DB
+	 */
+	while ((i = getopt(argc, argv, "as:")) != EOF) {
+		switch(i) {
+		case 'a':
+			alldbs++;
+			break;
+		case 's':
+			subname = optarg;
+			break;
+		default:
+			fprintf(stderr, "%s: unrecognized option -%c\n", prog, optopt);
+			usage(prog);
+		}
+	}
+
+	if (optind != argc - 1)
+		usage(prog);
 
+	envname = argv[optind];
 	rc = mdb_env_create(&env);
 
-	if (argc > 2) {
+	if (alldbs || subname) {
 		mdb_env_set_maxdbs(env, 4);
-		subname = argv[2];
 	}
 
-	rc = mdb_env_open(env, envname, MDB_RDONLY, 0);
+	rc = mdb_env_open(env, envname, MDB_RDONLY, 0664);
 	if (rc) {
-		printf("mdb_env_open failed, error %d\n", rc);
+		printf("mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
 		goto env_close;
 	}
 	rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
 	if (rc) {
-		printf("mdb_txn_begin failed, error %d\n", rc);
+		printf("mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
 		goto env_close;
 	}
 	rc = mdb_open(txn, subname, 0, &dbi);
 	if (rc) {
-		printf("mdb_open failed, error %d\n", rc);
+		printf("mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
 		goto txn_abort;
 	}
    
 	rc = mdb_stat(txn, dbi, &mst);
-	printf("Page size: %u\n", mst.ms_psize);
-	printf("Tree depth: %u\n", mst.ms_depth);
-	printf("Branch pages: %zu\n", mst.ms_branch_pages);
-	printf("Leaf pages: %zu\n", mst.ms_leaf_pages);
-	printf("Overflow pages: %zu\n", mst.ms_overflow_pages);
-	printf("Entries: %zu\n", mst.ms_entries);
+	if (rc) {
+		printf("mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc));
+		goto txn_abort;
+	}
+	prstat(&mst);
+
+	if (alldbs) {
+		MDB_cursor *cursor;
+		MDB_val key;
+
+		rc = mdb_cursor_open(txn, dbi, &cursor);
+		if (rc) {
+			printf("mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
+			goto txn_abort;
+		}
+		while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT)) == 0) {
+			char *str = malloc(key.mv_size+1);
+			MDB_dbi db2;
+			memcpy(str, key.mv_data, key.mv_size);
+			str[key.mv_size] = '\0';
+			rc = mdb_open(txn, str, 0, &db2);
+			if (rc == MDB_SUCCESS)
+				printf("\n%s\n", str);
+			free(str);
+			if (rc) continue;
+			rc = mdb_stat(txn, db2, &mst);
+			if (rc) {
+				printf("mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc));
+				goto txn_abort;
+			}
+			prstat(&mst);
+			mdb_close(env, db2);
+		}
+		mdb_cursor_close(cursor);
+	}
+
 	mdb_close(env, dbi);
 txn_abort:
 	mdb_txn_abort(txn);
diff --git a/libraries/libmdb/mdb_stata.c b/libraries/libmdb/mdb_stata.c
deleted file mode 100644
index 7cfebb4914..0000000000
--- a/libraries/libmdb/mdb_stata.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* mdb_stat.c - memory-mapped database status tool */
-/*
- * Copyright 2011 Howard Chu, Symas Corp.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "mdb.h"
-
-int main(int argc,char * argv[])
-{
-	int rc;
-	MDB_env *env;
-	MDB_txn *txn;
-	MDB_dbi dbi;
-	MDB_stat mst;
-	MDB_cursor *cursor;
-	MDB_val key;
-	char *envname = argv[1];
-
-	rc = mdb_env_create(&env);
-
-	mdb_env_set_maxdbs(env, 4);
-
-	rc = mdb_env_open(env, envname, MDB_RDONLY, 0);
-	if (rc) {
-		printf("mdb_env_open failed, error %d\n", rc);
-		goto env_close;
-	}
-	rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
-	if (rc) {
-		printf("mdb_txn_begin failed, error %d\n", rc);
-		goto env_close;
-	}
-	rc = mdb_open(txn, NULL, 0, &dbi);
-	if (rc) {
-		printf("mdb_open failed, error %d\n", rc);
-		goto txn_abort;
-	}
-   
-	rc = mdb_stat(txn, dbi, &mst);
-	printf("Page size: %u\n", mst.ms_psize);
-	printf("Tree depth: %u\n", mst.ms_depth);
-	printf("Branch pages: %zu\n", mst.ms_branch_pages);
-	printf("Leaf pages: %zu\n", mst.ms_leaf_pages);
-	printf("Overflow pages: %zu\n", mst.ms_overflow_pages);
-	printf("Entries: %zu\n", mst.ms_entries);
-
-	rc = mdb_cursor_open(txn, dbi, &cursor);
-	while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT)) == 0) {
-		char *str = malloc(key.mv_size+1);
-		MDB_dbi db2;
-		memcpy(str, key.mv_data, key.mv_size);
-		str[key.mv_size] = '\0';
-		printf("\n%s\n", str);
-		rc = mdb_open(txn, str, 0, &db2);
-		if (rc) break;
-		free(str);
-		rc = mdb_stat(txn, db2, &mst);
-		printf("Tree depth: %u\n", mst.ms_depth);
-		printf("Branch pages: %zu\n", mst.ms_branch_pages);
-		printf("Leaf pages: %zu\n", mst.ms_leaf_pages);
-		printf("Overflow pages: %zu\n", mst.ms_overflow_pages);
-		printf("Entries: %zu\n", mst.ms_entries);
-		mdb_close(env, db2);
-	}
-	mdb_cursor_close(cursor);
-	mdb_close(env, dbi);
-txn_abort:
-	mdb_txn_abort(txn);
-env_close:
-	mdb_env_close(env);
-
-	return rc ? EXIT_FAILURE : EXIT_SUCCESS;
-}
-- 
GitLab