View | Details | Raw Unified | Return to bug 41854
Collapse All | Expand All

(-)java/src/org/apache/xindice/tools/DatabaseRebuild.java (-81 / +168 lines)
Lines 22-27 Link Here
22
import org.apache.xindice.xml.dom.DOMParser;
22
import org.apache.xindice.xml.dom.DOMParser;
23
import org.apache.xindice.core.filer.BTreeFiler;
23
import org.apache.xindice.core.filer.BTreeFiler;
24
import org.apache.xindice.core.filer.BTreeCallback;
24
import org.apache.xindice.core.filer.BTreeCallback;
25
import org.apache.xindice.core.filer.BTreeException;
25
import org.apache.xindice.core.data.Value;
26
import org.apache.xindice.core.data.Value;
26
import org.apache.xindice.core.data.Key;
27
import org.apache.xindice.core.data.Key;
27
import org.apache.xindice.core.Database;
28
import org.apache.xindice.core.Database;
Lines 29-35 Link Here
29
import org.apache.xindice.core.DBException;
30
import org.apache.xindice.core.DBException;
30
import org.apache.xindice.core.indexer.Indexer;
31
import org.apache.xindice.core.indexer.Indexer;
31
import org.apache.xindice.util.Configuration;
32
import org.apache.xindice.util.Configuration;
32
import org.apache.xindice.util.XindiceException;
33
import org.apache.commons.logging.Log;
34
import org.apache.commons.logging.LogFactory;
33
35
34
import java.io.File;
36
import java.io.File;
35
import java.io.IOException;
37
import java.io.IOException;
Lines 41-192 Link Here
41
 */
43
 */
42
public class DatabaseRebuild {
44
public class DatabaseRebuild {
43
45
46
    private static final int CMD_ALL = 0;
44
    private static final int CMD_COPY  = 1;
47
    private static final int CMD_COPY  = 1;
45
    private static final int CMD_INDEX = 2;
48
    private static final int CMD_INDEX = 2;
46
49
47
    private static Database db;
50
    private static final char NOT_RAN = '_';
48
    private static String path;
51
    private static final char SUCCESS = '*';
49
    private static boolean removeBackupFiles;
52
    private static final char ERROR = '!';
50
    private static int command;
51
53
54
    private static final Log log = LogFactory.getLog(DatabaseRebuild.class);
52
55
53
    public static void main(String[] args) throws Exception {
56
    public static void main(String[] args) throws Exception {
54
        if (args.length < 2 || !("copy".equals(args[0]) || "index".equals(args[0])) ||
57
        if (args.length < 2 || args[1] == null || args[1].length() == 0 ||
55
            args[1] == null || args[1].length() == 0) {
58
            !("copy".equals(args[0]) || "index".equals(args[0]) || "rebuild".equals(args[0]))) {
56
            usage();
59
            usage();
57
            return;
60
            System.exit(1);
58
        }
61
        }
59
62
60
        command = "copy".equals(args[0]) ? CMD_COPY : CMD_INDEX;
63
        int command;
64
        if ("copy".equals(args[0])) {
65
            command = CMD_COPY;
66
        } else if ("index".equals(args[0])) {
67
            command = CMD_INDEX;
68
        } else {
69
            command = CMD_ALL;
70
        }
71
61
        String dbLocation = args[1];
72
        String dbLocation = args[1];
62
        if (args.length > 2 && args[2].equals("--remove")) {
73
63
            removeBackupFiles = true;
74
        File location = new File(dbLocation);
75
        dbLocation = location.getAbsolutePath();
76
        String name = location.getName();
77
78
        if ("".equals(name) || !location.exists() || !location.isDirectory()) {
79
            System.out.println("Database path must point to existing database directory");
80
            System.exit(1);
64
        }
81
        }
65
82
66
        String  config = "<root-collection dbroot='" + dbLocation + "/' name='" + dbLocation + "'/>";
83
        // create minimal database configuration instead of trying to locate system.xml
67
        db = new Database();
84
        String  config = "<root-collection dbroot='" + dbLocation + "/' name='" + name + "'/>";
85
        Database db = new Database();
68
86
87
        boolean status = true;
69
        try {
88
        try {
89
            System.out.println();
90
            System.out.println("CI\tCollection name");
91
70
            db.setConfig(new Configuration(DOMParser.toDocument(config)));
92
            db.setConfig(new Configuration(DOMParser.toDocument(config)));
71
93
72
            path = db.getCollectionRoot().getPath();
94
            if (log.isInfoEnabled()) {
73
            processChildCollections("/");
95
                log.info("Rebuilding collections...");
96
            }
97
            status = processCollection(db, command);
74
        } finally {
98
        } finally {
75
            db.close();
99
            db.close();
100
101
            System.out.println();
102
            if (status) {
103
                System.out.println("Rebuilding database was successfull");
104
            } else {
105
                System.out.println("Rebuilding database failed. Please check logs for more detail");
106
            }
107
108
            System.exit(status ? 0 : 2);
76
        }
109
        }
110
77
    }
111
    }
78
112
79
    private static void usage() {
113
    private static void usage() {
80
        System.out.println("Commands:");
114
        System.out.println("Commands:");
81
        System.out.println("copy <db location> [--remove]");
115
        System.out.println("copy <db location> -v");
82
        System.out.println("index <db location>");
116
        System.out.println("index <db location> -v");
117
        System.out.println("rebuild <db location> -v");
83
    }
118
    }
84
119
85
    private static void processChildCollections(String colRoot) {
120
    private static boolean processCollection(Collection col, int command) {
86
        System.out.println("Getting child collections for " + colRoot);
121
        String name = col.getCanonicalName();
122
        boolean status;
123
87
        try {
124
        try {
88
            // Get a Collection reference
125
            if (log.isInfoEnabled()) {
89
            Collection col = db.getCollection(colRoot);
126
                log.info("Processing collection " + name);
90
            if (col == null) {
91
                System.out.println("Error fetching collection '" + colRoot + "'");
92
                return;
93
            }
127
            }
94
128
95
            processCollection(col, colRoot);
129
            char copy = NOT_RAN;
130
            char index = NOT_RAN;
131
            switch (command) {
132
                case CMD_COPY:
133
                    status = rebuildCollection(col);
134
                    copy = status ? SUCCESS : ERROR;
135
                    break;
96
136
137
                case CMD_INDEX:
138
                    status = rebuildIndex(col);
139
                    index = status ? SUCCESS : ERROR;
140
                    break;
141
                default:
142
                    status = rebuildCollection(col);
143
                    copy = status ? SUCCESS : ERROR;
144
                    if (status) {
145
                        status = rebuildIndex(col);
146
                        index = status ? SUCCESS : ERROR;
147
                    }
148
                    break;
149
            }
150
151
            System.out.println(Character.toString(copy) + Character.toString(index) + "\t" + name);
152
97
            String[] colNames = col.listCollections();
153
            String[] colNames = col.listCollections();
98
            for (int i = 0; i < colNames.length; i++) {
154
            for (int i = 0; i < colNames.length; i++) {
99
                processChildCollections(colRoot + colNames[i] + "/");
155
                boolean result = processCollection(col.getCollection(colNames[i]), command);
156
                status = status && result;
100
            }
157
            }
101
        } catch (Exception e) {
158
        } catch (DBException e) {
102
            System.out.println("Got an excefption when processing collection: " + colRoot);
159
            log.error("Got an exception when processing collection " + name, e);
103
            e.printStackTrace();
160
161
            return false;
104
        }
162
        }
163
164
        return status;
105
    }
165
    }
106
166
107
    private static void processCollection(Collection col, String location) throws XindiceException, IOException {
167
    private static boolean rebuildCollection(Collection col) {
108
        switch (command) {
168
        String canonicalName = col.getCanonicalName();
109
            case CMD_INDEX:
110
                rebuildIndex(col);
111
                break;
112
169
113
            case CMD_COPY:
170
        if (!(col.getFiler() instanceof BTreeFiler)) {
114
                rebuildCollection(col, location, col.getName());
171
            if (log.isInfoEnabled()) {
115
                break;
172
                log.info("Filer for collection " + canonicalName + " is not BTreeFiler. Skipping...");
173
            }
174
            return true;
116
        }
175
        }
117
    }
118
176
119
    private static void rebuildCollection(Collection col, String location, String name) throws XindiceException, IOException {
177
        // close collection's filer
120
        if (!(col.getFiler() instanceof BTreeFiler)) {
178
        try {
121
            System.out.println("Filer for collection " + location + " is not BTreeFiler. Skipping...");
179
            col.getFiler().close();
122
            return;
180
        } catch (DBException e) {
181
            log.error("Could not close filer for collection " + canonicalName, e);
182
            return false;
123
        }
183
        }
124
184
125
        // close collection and its filer
126
        col.close();
127
128
        System.out.println("Processing collection " + location);
129
130
        File root = new File(path + location);
131
132
        // backup
133
        String fileName = path + location + "/" + name;
134
        // FIXME What if copy fails. It's probably a better idea to first make a copy,
135
        //       and rename after that?
136
        new File(fileName + ".tbl").renameTo(new File(fileName + ".old.tbl"));
137
138
        // prepare
185
        // prepare
139
        BTreeCopy filer = new BTreeCopy();
186
        BTreeCopy oldFiler = new BTreeCopy();
140
        filer.setLocation(root, name + ".old");
187
        oldFiler.setLocation(col.getCollectionRoot(), col.getName());
141
        filer.setConfig(col.getFiler().getConfig());
188
        oldFiler.setConfig(col.getFiler().getConfig());
142
        if (!filer.exists()) {
189
        String oldFileName = oldFiler.getFilerFile().getAbsolutePath();
143
            System.out.println("Filer for " + fileName + ".old.tbl does not exists");
190
        if (!oldFiler.exists()) {
144
            return;
191
            log.error("Filer for " + oldFileName + " does not exists");
192
            return false;
145
        }
193
        }
146
194
147
        BTreeFiler newFiler = new BTreeFiler();
195
        BTreeCopy newFiler = new BTreeCopy();
148
        newFiler.setLocation(root, name);
196
        newFiler.setLocation(col.getCollectionRoot(), col.getName() + ".rebuild");
149
        newFiler.setConfig(col.getFiler().getConfig());
197
        newFiler.setConfig(col.getFiler().getConfig());
198
        String newFileName = newFiler.getFilerFile().getAbsolutePath();
150
        if (newFiler.exists()) {
199
        if (newFiler.exists()) {
151
            System.out.println("Filer for " + fileName + ".tbl already exists");
200
            log.error("Filer for " + newFileName + " already exists");
152
            return;
201
            return false;
153
        }
202
        }
154
203
155
        // copy
204
        // copy
156
        newFiler.create();
205
        if (!copy(oldFiler, newFiler, canonicalName)) {
206
            newFiler.deleteFile();
207
            return false;
208
        }
209
210
        oldFiler.deleteFile();
211
        if (!newFiler.getFilerFile().renameTo(oldFiler.getFilerFile())) {
212
            log.error("Could not rename successfully rebuilt file " + newFileName + " to " + oldFileName);
213
            return false;
214
        }
215
157
        try {
216
        try {
158
            filer.open();
217
            col.getFiler().open();
218
        } catch (DBException e) {
219
            log.error("Could not open new file " + oldFileName, e);
220
            return false;
221
        }
222
223
        return true;
224
    }
225
226
    private static boolean copy(BTreeCopy oldFiler, BTreeCopy newFiler, String canonicalName) {
227
        try {
228
            newFiler.create();
229
            oldFiler.open();
159
            newFiler.open();
230
            newFiler.open();
160
231
            oldFiler.copy(newFiler);
161
            filer.copy(newFiler);
232
        } catch (Exception e) {
162
            if (removeBackupFiles) {
233
            log.error("Error copying collection " + canonicalName, e);
163
                filer.deleteFile();
234
            return false;
164
            }
165
        } finally {
235
        } finally {
166
            try {
236
            try {
167
                filer.close();
237
                oldFiler.close();
168
            } catch (Exception e) {
238
            } catch (DBException e) {
169
                e.printStackTrace();
239
                if (log.isWarnEnabled()) log.warn(e);
170
            }
240
            }
171
            try {
241
            try {
172
                newFiler.close();
242
                newFiler.close();
173
            } catch (Exception e) {
243
            } catch (DBException e) {
174
                e.printStackTrace();
244
                if (log.isWarnEnabled()) log.warn(e);
175
            }
245
            }
176
        }
246
        }
247
248
        return true;
177
    }
249
    }
178
250
179
    private static void rebuildIndex(Collection col) throws DBException {
251
    private static boolean rebuildIndex(Collection col) {
180
        if (col.getFiler() != null) {
252
        if (col.getFiler() == null) {
253
            return true;
254
        }
255
256
        try {
181
            String[] list = col.listIndexers();
257
            String[] list = col.listIndexers();
182
            for (int i = 0; i < list.length; i++) {
258
            for (int i = 0; i < list.length; i++) {
183
                Indexer idx = col.getIndexer(list[i]);
259
                Indexer idx = col.getIndexer(list[i]);
184
                Configuration idxConf = idx.getConfig();
260
                Configuration idxConf = idx.getConfig();
185
                System.out.println("Rebuilding index " + list[i] + " for collection " + col.getName());
261
                if (log.isInfoEnabled()) {
262
                    log.info("Rebuilding index " + list[i] + " for collection " + col.getCanonicalName());
263
                }
186
                col.dropIndexer(idx);
264
                col.dropIndexer(idx);
187
                col.createIndexer(idxConf);
265
                col.createIndexer(idxConf);
188
            }
266
            }
267
        } catch (DBException e) {
268
            log.error("Could not rebuild index for collection " + col.getCanonicalName(), e);
269
            return false;
189
        }
270
        }
271
272
        return true;
190
    }
273
    }
191
274
192
    private static class BTreeCopy extends BTreeFiler {
275
    private static class BTreeCopy extends BTreeFiler {
Lines 194-206 Link Here
194
            return super.readValue(pointer);
277
            return super.readValue(pointer);
195
        }
278
        }
196
279
197
        private void copy(BTreeFiler newFiler) throws XindiceException, IOException {
280
        private void copy(BTreeFiler newFiler) throws IOException, BTreeException {
198
            query(null, new CopyCallback(this, newFiler));
281
            query(null, new CopyCallback(this, newFiler));
199
        }
282
        }
200
283
201
        private boolean deleteFile() {
284
        private boolean deleteFile() {
202
            return getFile().delete();
285
            return getFile().delete();
203
        }
286
        }
287
288
        private File getFilerFile() {
289
            return getFile();
290
        }
204
    }
291
    }
205
292
206
    private static class CopyCallback implements BTreeCallback {
293
    private static class CopyCallback implements BTreeCallback {

Return to bug 41854