Avoid complaints about empty address lists.
[notmuch] / xapian-dump.cc
1 /* xapian-dump: Create a textual dump of a Xapian database.
2  *
3  * Copyright © 2009 Carl Worth
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see http://www.gnu.org/licenses/ .
17  *
18  * Author: Carl Worth <cworth@cworth.org>
19  */
20
21 /* Currently the dumped data includes:
22  *
23  *      All document IDs
24  *
25  * And for each document ID:
26  *
27  *      Document data
28  *      All document terms
29  *      All document values
30  */
31
32 #include <cstdlib>
33 #include <iostream>
34 #include <algorithm>
35
36 #include <xapian.h>
37
38 using namespace std;
39
40 vector<int> UNSERIALIZE;
41
42 static void
43 print_document_terms (Xapian::Document doc)
44 {
45     Xapian::TermIterator i;
46
47     printf ("    Terms:\n");
48
49     for (i = doc.termlist_begin (); i != doc.termlist_end (); i++)
50         cout << "\t" << *i << endl;
51 }
52
53 static int
54 vector_int_contains (vector<int> v, int i)
55 {
56     vector<int>::iterator result;
57
58     result = find (v.begin(), v.end(), i);
59
60     return result != v.end();
61 }
62
63 static void
64 print_document_values (Xapian::Document doc)
65 {
66     Xapian::ValueIterator i;
67     int value_no, value_int;
68     double value_float;
69
70     printf ("    Values:\n");
71
72     for (i = doc.values_begin (); i != doc.values_end (); i++) {
73         value_no = i.get_valueno();
74
75         cout << "\t" << i.get_valueno() << ": ";
76
77         if (vector_int_contains (UNSERIALIZE, value_no)) {
78             value_float = Xapian::sortable_unserialise (*i);
79             value_int = value_float;
80             if (value_int == value_float)
81                 cout << value_int;
82             else
83                 cout << value_float;
84         } else {
85             cout << *i;
86         }
87
88         cout << endl;
89     }
90 }
91
92 static void
93 print_document (Xapian::Database db, Xapian::docid id)
94 {
95     Xapian::Document doc;
96
97     printf ("Document %u:\n", id);
98
99     doc = db.get_document (id);
100
101     printf ("    Data:\n");
102     cout << "\t" << doc.get_data () << endl;
103
104     print_document_terms (doc);
105
106     print_document_values (doc);
107 }
108
109 int
110 main (int argc, char *argv[])
111 {
112     const char *database_path;
113     int i;
114
115     if (argc < 2) {
116         fprintf (stderr, "Usage: %s <path-to-xapian-database> [value_nos...]\n",
117                  argv[0]);
118         fprintf (stderr, "Dumps data from the given database.\n");
119         fprintf (stderr, "The values corresponding to any value numbers given on the command line\n");
120         fprintf (stderr, "will be unserialized to an before being printed.\n");
121         exit (1);
122     }
123
124     database_path = argv[1];
125
126     UNSERIALIZE = vector<int> ();
127
128     for (i = 2; i < argc; i++)
129         UNSERIALIZE.push_back (atoi (argv[i]));
130
131     try {
132
133         Xapian::Database db;
134         Xapian::PostingIterator i;
135         Xapian::docid doc_id;
136
137         db = Xapian::Database (database_path);
138         for (i = db.postlist_begin (""); i != db.postlist_end (""); i++) {
139             doc_id = *i;
140
141             print_document (db, doc_id);
142         }
143
144     } catch (const Xapian::Error &error) {
145         cerr << "A Xapian exception occurred: " << error.get_msg () << endl;
146         exit (1);
147     }
148
149     return 0;
150 }