b28c274c7d475623e1f59e9d7360ed8bab9c2733
[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  *      All terms
28  *      All values
29  *
30  * Things not yet dumped include:
31  *
32  * Data associated with a document.
33  */
34
35 #include <cstdlib>
36 #include <iostream>
37 #include <algorithm>
38
39 #include <xapian.h>
40
41 using namespace std;
42
43 vector<int> UNSERIALIZE;
44
45 static void
46 print_document_terms (Xapian::Document doc)
47 {
48     Xapian::TermIterator i;
49
50     printf ("Terms:\n");
51
52     for (i = doc.termlist_begin (); i != doc.termlist_end (); i++)
53         cout << "\t" << *i << endl;
54 }
55
56 static int
57 vector_int_contains (vector<int> v, int i)
58 {
59     vector<int>::iterator result;
60
61     result = find (v.begin(), v.end(), i);
62
63     return result != v.end();
64 }
65
66 static void
67 print_document_values (Xapian::Document doc)
68 {
69     Xapian::ValueIterator i;
70     int value_no, value_int;
71     double value_float;
72
73     printf ("Values:\n");
74
75     for (i = doc.values_begin (); i != doc.values_end (); i++) {
76         value_no = i.get_valueno();
77
78         cout << "\t" << i.get_valueno() << ": ";
79
80         if (vector_int_contains (UNSERIALIZE, value_no)) {
81             value_float = Xapian::sortable_unserialise (*i);
82             value_int = value_float;
83             if (value_int == value_float)
84                 cout << value_int;
85             else
86                 cout << value_float;
87         } else {
88             cout << *i;
89         }
90
91         cout << endl;
92     }
93 }
94
95 static void
96 print_document (Xapian::Database db, Xapian::docid id)
97 {
98     Xapian::Document doc;
99
100     printf ("Document %u:\n", id);
101
102     doc = db.get_document (id);
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 }