Source Code Cross Referenced for Recover.java in  » Database-DBMS » h2database » org » h2 » tools » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » h2database » org.h2.tools 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
0003:         * (http://h2database.com/html/license.html).
0004:         * Initial Developer: H2 Group
0005:         */
0006:        package org.h2.tools;
0007:
0008:        import java.io.BufferedInputStream;
0009:        import java.io.BufferedReader;
0010:        import java.io.BufferedWriter;
0011:        import java.io.ByteArrayInputStream;
0012:        import java.io.DataInputStream;
0013:        import java.io.FileInputStream;
0014:        import java.io.IOException;
0015:        import java.io.InputStream;
0016:        import java.io.InputStreamReader;
0017:        import java.io.OutputStream;
0018:        import java.io.PrintWriter;
0019:        import java.io.Reader;
0020:        import java.sql.SQLException;
0021:        import java.util.ArrayList;
0022:        import java.util.HashMap;
0023:        import java.util.HashSet;
0024:        import java.util.Iterator;
0025:        import java.util.Map;
0026:        import java.util.Map.Entry;
0027:
0028:        import org.h2.command.Parser;
0029:        import org.h2.engine.Constants;
0030:        import org.h2.engine.Database;
0031:        import org.h2.engine.DbObject;
0032:        import org.h2.engine.MetaRecord;
0033:        import org.h2.log.LogFile;
0034:        import org.h2.message.Message;
0035:        import org.h2.result.SimpleRow;
0036:        import org.h2.security.SHA256;
0037:        import org.h2.store.DataHandler;
0038:        import org.h2.store.DataPage;
0039:        import org.h2.store.DiskFile;
0040:        import org.h2.store.FileLister;
0041:        import org.h2.store.FileStore;
0042:        import org.h2.store.FileStoreInputStream;
0043:        import org.h2.util.ByteUtils;
0044:        import org.h2.util.FileUtils;
0045:        import org.h2.util.IOUtils;
0046:        import org.h2.util.ObjectArray;
0047:        import org.h2.util.ObjectUtils;
0048:        import org.h2.util.RandomUtils;
0049:        import org.h2.util.SmallLRUCache;
0050:        import org.h2.value.Value;
0051:        import org.h2.value.ValueLob;
0052:
0053:        /**
0054:         * Dumps the contents of a database file to a human readable text file. This
0055:         * text file can be used to recover most of the data. This tool does not open
0056:         * the database and can be used even if the database files are corrupted. A
0057:         * database can get corrupted if there is a bug in the database engine or file
0058:         * system software, or if an application writes into the database file that
0059:         * doesn't understand the the file format, or if there is a hardware problem.
0060:         */
0061:        public class Recover implements  DataHandler {
0062:
0063:            private String databaseName;
0064:            private boolean textStorage;
0065:            private int block;
0066:            private int blockCount;
0067:            private int storageId;
0068:            private int recordLength;
0069:            private int valueId;
0070:            private boolean log;
0071:            private boolean lobFilesInDirectories;
0072:
0073:            private void showUsage() {
0074:                System.out.println("java " + getClass().getName()
0075:                        + " [-dir <dir>] [-db <database>] [-log true]");
0076:                System.out
0077:                        .println("See also http://h2database.com/javadoc/org/h2/tools/Recover.html");
0078:            }
0079:
0080:            /**
0081:             * The command line interface for this tool.
0082:             * The options must be split into strings like this: "-db", "test",...
0083:             * Options are case sensitive. The following options are supported:
0084:             * <ul>
0085:             * <li>-help or -? (print the list of options)
0086:             * </li><li>-dir database directory (the default is the current directory)
0087:             * </li><li>-db database name (all databases if no name is specified)
0088:             * </li><li>-log {true|false} (log additional messages)
0089:             * </li></ul>
0090:             *
0091:             * @param args the command line arguments
0092:             * @throws SQLException
0093:             */
0094:            public static void main(String[] args) throws SQLException {
0095:                new Recover().run(args);
0096:            }
0097:
0098:            private void run(String[] args) throws SQLException {
0099:                String dir = ".";
0100:                String db = null;
0101:                boolean removePassword = false;
0102:                for (int i = 0; args != null && i < args.length; i++) {
0103:                    if ("-dir".equals(args[i])) {
0104:                        dir = args[++i];
0105:                    } else if ("-db".equals(args[i])) {
0106:                        db = args[++i];
0107:                    } else if ("-removePassword".equals(args[i])) {
0108:                        removePassword = true;
0109:                        log = true;
0110:                    } else if ("-log".equals(args[i])) {
0111:                        log = Boolean.valueOf(args[++i]).booleanValue();
0112:                    } else {
0113:                        showUsage();
0114:                        return;
0115:                    }
0116:                }
0117:                if (removePassword) {
0118:                    removePassword(dir, db);
0119:                } else {
0120:                    process(dir, db);
0121:                }
0122:            }
0123:
0124:            /**
0125:             * INTERNAL
0126:             */
0127:            public static Reader readClob(String fileName) throws IOException {
0128:                return new BufferedReader(new InputStreamReader(
0129:                        readBlob(fileName)));
0130:            }
0131:
0132:            /**
0133:             * INTERNAL
0134:             */
0135:            public static InputStream readBlob(String fileName)
0136:                    throws IOException {
0137:                return new BufferedInputStream(new FileInputStream(fileName));
0138:            }
0139:
0140:            private void removePassword(String dir, String db)
0141:                    throws SQLException {
0142:                ArrayList list = FileLister.getDatabaseFiles(dir, db, true);
0143:                for (int i = 0; i < list.size(); i++) {
0144:                    String fileName = (String) list.get(i);
0145:                    if (fileName.endsWith(Constants.SUFFIX_DATA_FILE)) {
0146:                        removePassword(fileName);
0147:                    }
0148:                }
0149:            }
0150:
0151:            private void log(String message) {
0152:                if (log) {
0153:                    System.out.println(message);
0154:                }
0155:            }
0156:
0157:            private void logError(String message, Throwable t) {
0158:                System.out.println(message + ": " + t.toString());
0159:                if (log) {
0160:                    t.printStackTrace();
0161:                }
0162:            }
0163:
0164:            private void removePassword(String fileName) throws SQLException {
0165:                setDatabaseName(fileName.substring(fileName.length()
0166:                        - Constants.SUFFIX_DATA_FILE.length()));
0167:                textStorage = Database.isTextStorage(fileName, false);
0168:                byte[] magic = Database.getMagic(textStorage);
0169:                FileStore store = FileStore.open(null, fileName, "rw", magic);
0170:                long length = store.length();
0171:                int offset = FileStore.HEADER_LENGTH;
0172:                int blockSize = DiskFile.BLOCK_SIZE;
0173:                int blocks = (int) (length / blockSize);
0174:                blockCount = 1;
0175:                for (int block = 0; block < blocks; block += blockCount) {
0176:                    store.seek(offset + (long) block * blockSize);
0177:                    byte[] bytes = new byte[blockSize];
0178:                    DataPage s = DataPage.create(this , bytes);
0179:                    long start = store.getFilePointer();
0180:                    store.readFully(bytes, 0, blockSize);
0181:                    blockCount = s.readInt();
0182:                    storageId = -1;
0183:                    recordLength = -1;
0184:                    valueId = -1;
0185:                    if (blockCount == 0) {
0186:                        // free block
0187:                        blockCount = 1;
0188:                        continue;
0189:                    } else if (blockCount < 0) {
0190:                        blockCount = 1;
0191:                        continue;
0192:                    }
0193:                    try {
0194:                        s.checkCapacity(blockCount * blockSize);
0195:                    } catch (OutOfMemoryError e) {
0196:                        blockCount = 1;
0197:                        continue;
0198:                    }
0199:                    if (blockCount > 1) {
0200:                        store.readFully(s.getBytes(), blockSize, blockCount
0201:                                * blockSize - blockSize);
0202:                    }
0203:                    try {
0204:                        s.check(blockCount * blockSize);
0205:                    } catch (SQLException e) {
0206:                        blockCount = 1;
0207:                        continue;
0208:                    }
0209:                    storageId = s.readInt();
0210:                    if (storageId != 0) {
0211:                        continue;
0212:                    }
0213:                    recordLength = s.readInt();
0214:                    if (recordLength <= 0) {
0215:                        continue;
0216:                    }
0217:                    Value[] data;
0218:                    try {
0219:                        data = new Value[recordLength];
0220:                    } catch (Throwable e) {
0221:                        continue;
0222:                    }
0223:                    for (valueId = 0; valueId < recordLength; valueId++) {
0224:                        try {
0225:                            data[valueId] = s.readValue();
0226:                        } catch (Throwable e) {
0227:                            continue;
0228:                        }
0229:                    }
0230:                    if (storageId == 0) {
0231:                        try {
0232:                            String sql = data[3].getString();
0233:                            if (!sql.startsWith("CREATE USER ")) {
0234:                                continue;
0235:                            }
0236:                            int idx = sql.indexOf("SALT");
0237:                            if (idx < 0) {
0238:                                continue;
0239:                            }
0240:                            String userName = sql.substring("CREATE USER "
0241:                                    .length(), idx - 1);
0242:                            if (userName.startsWith("\"")) {
0243:                                // TODO doesn't work for all cases ("" inside user name)
0244:                                userName = userName.substring(1, userName
0245:                                        .length() - 1);
0246:                            }
0247:                            SHA256 sha = new SHA256();
0248:                            byte[] userPasswordHash = sha.getKeyPasswordHash(
0249:                                    userName, "".toCharArray());
0250:                            byte[] salt = RandomUtils
0251:                                    .getSecureBytes(Constants.SALT_LEN);
0252:                            byte[] passwordHash = sha.getHashWithSalt(
0253:                                    userPasswordHash, salt);
0254:                            boolean admin = sql.indexOf("ADMIN") >= 0;
0255:                            StringBuffer buff = new StringBuffer();
0256:                            buff.append("CREATE USER ");
0257:                            buff.append(Parser.quoteIdentifier(userName));
0258:                            buff.append(" SALT '");
0259:                            buff.append(ByteUtils.convertBytesToString(salt));
0260:                            buff.append("' HASH '");
0261:                            buff.append(ByteUtils
0262:                                    .convertBytesToString(passwordHash));
0263:                            buff.append("'");
0264:                            if (admin) {
0265:                                buff.append(" ADMIN");
0266:                            }
0267:                            byte[] replacement = buff.toString().getBytes();
0268:                            int at = ByteUtils.indexOf(s.getBytes(),
0269:                                    "CREATE USER ".getBytes(), 0);
0270:                            System.arraycopy(replacement, 0, s.getBytes(), at,
0271:                                    replacement.length);
0272:                            s.fill(blockCount * blockSize);
0273:                            s.updateChecksum();
0274:                            store.seek(start);
0275:                            store.write(s.getBytes(), 0, s.length());
0276:                            if (log) {
0277:                                System.out.println("User: " + userName);
0278:                            }
0279:                            break;
0280:                        } catch (Throwable e) {
0281:                            e.printStackTrace();
0282:                        }
0283:                    }
0284:                }
0285:                closeSilently(store);
0286:            }
0287:
0288:            /**
0289:             * Dumps the database.
0290:             *
0291:             * @param dir the directory
0292:             * @param db the database name (null for all databases)
0293:             * @throws SQLException
0294:             */
0295:            public static void execute(String dir, String db)
0296:                    throws SQLException {
0297:                new Recover().process(dir, db);
0298:            }
0299:
0300:            private void process(String dir, String db) throws SQLException {
0301:                ArrayList list = FileLister.getDatabaseFiles(dir, db, true);
0302:                for (int i = 0; i < list.size(); i++) {
0303:                    String fileName = (String) list.get(i);
0304:                    if (fileName.endsWith(Constants.SUFFIX_DATA_FILE)) {
0305:                        dumpData(fileName);
0306:                    } else if (fileName.endsWith(Constants.SUFFIX_INDEX_FILE)) {
0307:                        dumpIndex(fileName);
0308:                    } else if (fileName.endsWith(Constants.SUFFIX_LOG_FILE)) {
0309:                        dumpLog(fileName);
0310:                    } else if (fileName.endsWith(Constants.SUFFIX_LOB_FILE)) {
0311:                        dumpLob(fileName, true);
0312:                        dumpLob(fileName, false);
0313:                    }
0314:                }
0315:            }
0316:
0317:            private PrintWriter getWriter(String fileName, String suffix)
0318:                    throws IOException, SQLException {
0319:                fileName = fileName.substring(0, fileName.length() - 3);
0320:                String outputFile = fileName + suffix;
0321:                log("Created file: " + outputFile);
0322:                return new PrintWriter(new BufferedWriter(FileUtils
0323:                        .openFileWriter(outputFile, false)));
0324:            }
0325:
0326:            private void writeDataError(PrintWriter writer, String error,
0327:                    byte[] data, int dumpBlocks) throws IOException {
0328:                writer.println("-- ERROR:" + error + " block:" + block
0329:                        + " blockCount:" + blockCount + " storageId:"
0330:                        + storageId + " recordLength: " + recordLength
0331:                        + " valueId:" + valueId);
0332:                StringBuffer sb = new StringBuffer();
0333:                for (int i = 0; i < dumpBlocks * DiskFile.BLOCK_SIZE; i++) {
0334:                    int x = (data[i] & 0xff);
0335:                    if (x >= ' ' && x < 128) {
0336:                        sb.append((char) x);
0337:                    } else {
0338:                        sb.append('?');
0339:                    }
0340:                }
0341:                writer.println("-- dump: " + sb.toString());
0342:                sb = new StringBuffer();
0343:                for (int i = 0; i < dumpBlocks * DiskFile.BLOCK_SIZE; i++) {
0344:                    int x = (data[i] & 0xff);
0345:                    sb.append(' ');
0346:                    if (x < 16) {
0347:                        sb.append('0');
0348:                    }
0349:                    sb.append(Integer.toHexString(x));
0350:                }
0351:                writer.println("-- dump: " + sb.toString());
0352:            }
0353:
0354:            private void dumpLob(String fileName, boolean lobCompression) {
0355:                OutputStream out = null;
0356:                FileStore store = null;
0357:                int size = 0;
0358:                String n = fileName + (lobCompression ? ".comp" : "") + ".txt";
0359:                InputStream in = null;
0360:                try {
0361:                    out = FileUtils.openFileOutputStream(n, false);
0362:                    textStorage = Database.isTextStorage(fileName, false);
0363:                    byte[] magic = Database.getMagic(textStorage);
0364:                    store = FileStore.open(null, fileName, "r", magic);
0365:                    store.init();
0366:                    in = new BufferedInputStream(new FileStoreInputStream(
0367:                            store, this , lobCompression, false));
0368:                    byte[] buffer = new byte[Constants.IO_BUFFER_SIZE];
0369:                    while (true) {
0370:                        int l = in.read(buffer);
0371:                        if (l < 0) {
0372:                            break;
0373:                        }
0374:                        out.write(buffer, 0, l);
0375:                        size += l;
0376:                    }
0377:                    out.close();
0378:                } catch (Throwable e) {
0379:                    // this is usually not a problem, because we try both compressed and
0380:                    // uncompressed
0381:                    if (log) {
0382:                        logError(fileName, e);
0383:                    }
0384:                } finally {
0385:                    IOUtils.closeSilently(out);
0386:                    IOUtils.closeSilently(in);
0387:                    closeSilently(store);
0388:                }
0389:                if (size == 0) {
0390:                    try {
0391:                        FileUtils.delete(n);
0392:                    } catch (SQLException e) {
0393:                        logError(n, e);
0394:                    }
0395:                }
0396:            }
0397:
0398:            private void writeLogRecord(PrintWriter writer, DataPage s) {
0399:                try {
0400:                    recordLength = s.readInt();
0401:                    if (recordLength <= 0) {
0402:                        writeDataError(writer, "recordLength<0", s.getBytes(),
0403:                                blockCount);
0404:                        return;
0405:                    }
0406:                    Value[] data;
0407:                    try {
0408:                        data = new Value[recordLength];
0409:                    } catch (OutOfMemoryError e) {
0410:                        writeDataError(writer, "out of memory", s.getBytes(),
0411:                                blockCount);
0412:                        return;
0413:                    }
0414:                    StringBuffer sb = new StringBuffer();
0415:                    sb.append("//     data: ");
0416:                    for (valueId = 0; valueId < recordLength; valueId++) {
0417:                        try {
0418:                            Value v = s.readValue();
0419:                            data[valueId] = v;
0420:                            if (valueId > 0) {
0421:                                sb.append(", ");
0422:                            }
0423:                            sb.append(getSQL(v));
0424:                        } catch (Exception e) {
0425:                            if (log) {
0426:                                logError("log data", e);
0427:                            }
0428:                            writeDataError(writer, "exception " + e, s
0429:                                    .getBytes(), blockCount);
0430:                            continue;
0431:                        } catch (OutOfMemoryError e) {
0432:                            writeDataError(writer, "out of memory", s
0433:                                    .getBytes(), blockCount);
0434:                            continue;
0435:                        }
0436:                    }
0437:                    writer.println(sb.toString());
0438:                    writer.flush();
0439:                } catch (IOException e) {
0440:                    try {
0441:                        writeDataError(writer, "error: " + e.toString(), s
0442:                                .getBytes(), blockCount);
0443:                    } catch (IOException e2) {
0444:                        writeError(writer, e);
0445:                    }
0446:                }
0447:            }
0448:
0449:            private String getSQL(Value v) {
0450:                if (v instanceof  ValueLob) {
0451:                    ValueLob lob = (ValueLob) v;
0452:                    byte[] small = lob.getSmall();
0453:                    if (small == null) {
0454:                        String file = lob.getFileName();
0455:                        if (lob.getType() == Value.BLOB) {
0456:                            return "READ_BLOB('" + file + ".txt')";
0457:                        } else {
0458:                            return "READ_CLOB('" + file + ".txt')";
0459:                        }
0460:                    }
0461:                }
0462:                return v.getSQL();
0463:            }
0464:
0465:            private void setDatabaseName(String name) {
0466:                databaseName = name;
0467:                lobFilesInDirectories = FileUtils.exists(databaseName
0468:                        + Constants.SUFFIX_LOBS_DIRECTORY);
0469:            }
0470:
0471:            private void dumpLog(String fileName) throws SQLException {
0472:                PrintWriter writer = null;
0473:                FileStore store = null;
0474:                try {
0475:                    setDatabaseName(fileName.substring(fileName.length()
0476:                            - Constants.SUFFIX_LOG_FILE.length()));
0477:                    writer = getWriter(fileName, ".txt");
0478:                    textStorage = Database.isTextStorage(fileName, false);
0479:                    byte[] magic = Database.getMagic(textStorage);
0480:                    store = FileStore.open(null, fileName, "r", magic);
0481:                    long length = store.length();
0482:                    writer.println("// length: " + length);
0483:                    int offset = FileStore.HEADER_LENGTH;
0484:                    int blockSize = LogFile.BLOCK_SIZE;
0485:                    int blocks = (int) (length / blockSize);
0486:                    byte[] buff = new byte[blockSize];
0487:                    DataPage s = DataPage.create(this , buff);
0488:                    s.fill(3 * blockSize);
0489:                    int len = s.length();
0490:                    s.reset();
0491:                    if (length < FileStore.HEADER_LENGTH + len) {
0492:                        // this is an empty file
0493:                        writer.println("// empty file");
0494:                        return;
0495:                    }
0496:                    store.seek(offset);
0497:                    store.readFully(s.getBytes(), 0, len);
0498:                    int id = s.readInt();
0499:                    int firstUncommittedPos = s.readInt();
0500:                    int firstUnwrittenPos = s.readInt();
0501:                    writer.println("// id:" + id);
0502:                    writer.println("// firstUncommittedPos:"
0503:                            + firstUncommittedPos);
0504:                    writer.println("// firstUnwrittenPos:" + firstUnwrittenPos);
0505:                    int max = (int) (length / blockSize);
0506:                    writer.println("// max:" + max);
0507:                    while (true) {
0508:                        int pos = (int) (store.getFilePointer() / blockSize);
0509:                        if ((long) pos * blockSize >= length) {
0510:                            break;
0511:                        }
0512:                        buff = new byte[blockSize];
0513:                        store.readFully(buff, 0, blockSize);
0514:                        s = DataPage.create(this , buff);
0515:                        blocks = Math.abs(s.readInt());
0516:                        if (blocks > 1) {
0517:                            byte[] b2 = new byte[blocks * blockSize];
0518:                            System.arraycopy(buff, 0, b2, 0, blockSize);
0519:                            buff = b2;
0520:                            try {
0521:                                store.readFully(buff, blockSize, blocks
0522:                                        * blockSize - blockSize);
0523:                            } catch (SQLException e) {
0524:                                break;
0525:                            }
0526:                            s = DataPage.create(this , buff);
0527:                            s.check(blocks * blockSize);
0528:                        }
0529:                        s.reset();
0530:                        blocks = Math.abs(s.readInt());
0531:                        if (blocks == 0) {
0532:                            writer.println("// [" + pos + "] blocks: " + blocks
0533:                                    + " (end)");
0534:                            break;
0535:                        } else {
0536:                            char type = (char) s.readByte();
0537:                            int sessionId = s.readInt();
0538:                            if (type == 'P') {
0539:                                String transaction = s.readString();
0540:                                writer.println("//   prepared session:"
0541:                                        + sessionId + " tx:" + transaction);
0542:                            } else if (type == 'C') {
0543:                                writer.println("//   commit session:"
0544:                                        + sessionId);
0545:                            } else {
0546:                                int storageId = s.readInt();
0547:                                int recId = s.readInt();
0548:                                int blockCount = s.readInt();
0549:                                if (type != 'T') {
0550:                                    s.readDataPageNoSize();
0551:                                }
0552:                                switch (type) {
0553:                                case 'S': {
0554:                                    char fileType = (char) s.readByte();
0555:                                    int sumLength = s.readInt();
0556:                                    byte[] summary = new byte[sumLength];
0557:                                    if (sumLength > 0) {
0558:                                        s.read(summary, 0, sumLength);
0559:                                    }
0560:                                    writer.println("//   summary session:"
0561:                                            + sessionId + " fileType:"
0562:                                            + fileType + " sumLength:"
0563:                                            + sumLength);
0564:                                    dumpSummary(writer, summary);
0565:                                    break;
0566:                                }
0567:                                case 'T':
0568:                                    writer.println("//   truncate session:"
0569:                                            + sessionId + " storage:"
0570:                                            + storageId + " pos:" + recId
0571:                                            + " blockCount:" + blockCount);
0572:                                    break;
0573:                                case 'I':
0574:                                    writer.println("//   insert session:"
0575:                                            + sessionId + " storage:"
0576:                                            + storageId + " pos:" + recId
0577:                                            + " blockCount:" + blockCount);
0578:                                    writeLogRecord(writer, s);
0579:                                    break;
0580:                                case 'D':
0581:                                    writer.println("//   delete session:"
0582:                                            + sessionId + " storage:"
0583:                                            + storageId + " pos:" + recId
0584:                                            + " blockCount:" + blockCount);
0585:                                    writeLogRecord(writer, s);
0586:                                    break;
0587:                                default:
0588:                                    writer.println("//   type?:" + type
0589:                                            + " session:" + sessionId
0590:                                            + " storage:" + storageId + " pos:"
0591:                                            + recId + " blockCount:"
0592:                                            + blockCount);
0593:                                    break;
0594:                                }
0595:                            }
0596:                        }
0597:                    }
0598:                    writer.close();
0599:                } catch (Throwable e) {
0600:                    writeError(writer, e);
0601:                } finally {
0602:                    IOUtils.closeSilently(writer);
0603:                    closeSilently(store);
0604:                }
0605:            }
0606:
0607:            private void dumpSummary(PrintWriter writer, byte[] summary)
0608:                    throws SQLException {
0609:                if (summary == null || summary.length == 0) {
0610:                    writer.println("//     summary is empty");
0611:                    return;
0612:                }
0613:                try {
0614:                    DataInputStream in = new DataInputStream(
0615:                            new ByteArrayInputStream(summary));
0616:                    int b2 = in.readInt();
0617:                    for (int i = 0; i < b2 / 8; i++) {
0618:                        int x = in.read();
0619:                        if ((i % 8) == 0) {
0620:                            writer.print("//  ");
0621:                        }
0622:                        writer.print(" " + Long.toString(i * 8) + ":");
0623:                        for (int j = 0; j < 8; j++) {
0624:                            writer.print(((x & 1) == 1) ? "1" : "0");
0625:                            x >>>= 1;
0626:                        }
0627:                        if ((i % 8) == 7) {
0628:                            writer.println("");
0629:                        }
0630:                    }
0631:                    writer.println("//");
0632:                    int len = in.readInt();
0633:                    for (int i = 0; i < len; i++) {
0634:                        int storageId = in.readInt();
0635:                        if (storageId != -1) {
0636:                            writer.println("//     pos:"
0637:                                    + (i * DiskFile.BLOCKS_PER_PAGE)
0638:                                    + " storage:" + storageId);
0639:                        }
0640:                    }
0641:                    while (true) {
0642:                        int s = in.readInt();
0643:                        if (s < 0) {
0644:                            break;
0645:                        }
0646:                        int recordCount = in.readInt();
0647:                        writer.println("//     storage:" + s + " recordCount:"
0648:                                + recordCount);
0649:                    }
0650:                } catch (Throwable e) {
0651:                    writeError(writer, e);
0652:                }
0653:            }
0654:
0655:            private void dumpIndex(String fileName) throws SQLException {
0656:                PrintWriter writer = null;
0657:                FileStore store = null;
0658:                try {
0659:                    setDatabaseName(fileName.substring(fileName.length()
0660:                            - Constants.SUFFIX_INDEX_FILE.length()));
0661:                    writer = getWriter(fileName, ".txt");
0662:                    textStorage = Database.isTextStorage(fileName, false);
0663:                    byte[] magic = Database.getMagic(textStorage);
0664:                    store = FileStore.open(null, fileName, "r", magic);
0665:                    long length = store.length();
0666:                    int offset = FileStore.HEADER_LENGTH;
0667:                    int blockSize = DiskFile.BLOCK_SIZE;
0668:                    int blocks = (int) (length / blockSize);
0669:                    blockCount = 1;
0670:                    int[] pageOwners = new int[blocks
0671:                            / DiskFile.BLOCKS_PER_PAGE];
0672:                    for (int block = 0; block < blocks; block += blockCount) {
0673:                        store.seek(offset + (long) block * blockSize);
0674:                        byte[] buff = new byte[blockSize];
0675:                        DataPage s = DataPage.create(this , buff);
0676:                        store.readFully(buff, 0, blockSize);
0677:                        blockCount = s.readInt();
0678:                        storageId = -1;
0679:                        recordLength = -1;
0680:                        valueId = -1;
0681:                        if (blockCount == 0) {
0682:                            // free block
0683:                            blockCount = 1;
0684:                            continue;
0685:                        } else if (blockCount < 0) {
0686:                            writeDataError(writer, "blockCount<0",
0687:                                    s.getBytes(), 1);
0688:                            blockCount = 1;
0689:                            continue;
0690:                        } else if ((blockCount * blockSize) >= Integer.MAX_VALUE / 4) {
0691:                            writeDataError(writer, "blockCount=" + blockCount,
0692:                                    s.getBytes(), 1);
0693:                            blockCount = 1;
0694:                            continue;
0695:                        }
0696:                        try {
0697:                            s.checkCapacity(blockCount * blockSize);
0698:                        } catch (OutOfMemoryError e) {
0699:                            writeDataError(writer, "out of memory", s
0700:                                    .getBytes(), 1);
0701:                            blockCount = 1;
0702:                            continue;
0703:                        }
0704:                        if (blockCount > 1) {
0705:                            store.readFully(s.getBytes(), blockSize, blockCount
0706:                                    * blockSize - blockSize);
0707:                        }
0708:                        try {
0709:                            s.check(blockCount * blockSize);
0710:                        } catch (SQLException e) {
0711:                            writeDataError(writer, "wrong checksum", s
0712:                                    .getBytes(), 1);
0713:                            blockCount = 1;
0714:                            continue;
0715:                        }
0716:                        storageId = s.readInt();
0717:                        if (storageId < 0) {
0718:                            writeDataError(writer, "storageId<0", s.getBytes(),
0719:                                    blockCount);
0720:                            continue;
0721:                        }
0722:                        int page = block / DiskFile.BLOCKS_PER_PAGE;
0723:                        if (pageOwners[page] != 0
0724:                                && pageOwners[page] != storageId) {
0725:                            writeDataError(writer,
0726:                                    "double allocation, previous="
0727:                                            + pageOwners[page] + " now="
0728:                                            + storageId, s.getBytes(),
0729:                                    blockCount);
0730:                        } else {
0731:                            pageOwners[page] = storageId;
0732:                        }
0733:                        writer.println("// [" + block + "] page:" + page
0734:                                + " blocks:" + blockCount + " storage:"
0735:                                + storageId);
0736:                    }
0737:                    writer.close();
0738:                } catch (Throwable e) {
0739:                    writeError(writer, e);
0740:                } finally {
0741:                    IOUtils.closeSilently(writer);
0742:                    closeSilently(store);
0743:                }
0744:            }
0745:
0746:            private void dumpData(String fileName) throws SQLException {
0747:                PrintWriter writer = null;
0748:                FileStore store = null;
0749:                try {
0750:                    setDatabaseName(fileName.substring(0, fileName.length()
0751:                            - Constants.SUFFIX_DATA_FILE.length()));
0752:                    writer = getWriter(fileName, ".sql");
0753:                    writer
0754:                            .println("CREATE ALIAS IF NOT EXISTS READ_CLOB FOR \""
0755:                                    + this .getClass().getName()
0756:                                    + ".readClob\";");
0757:                    writer
0758:                            .println("CREATE ALIAS IF NOT EXISTS READ_BLOB FOR \""
0759:                                    + this .getClass().getName()
0760:                                    + ".readBlob\";");
0761:                    ObjectArray schema = new ObjectArray();
0762:                    HashSet objectIdSet = new HashSet();
0763:                    HashMap tableMap = new HashMap();
0764:                    textStorage = Database.isTextStorage(fileName, false);
0765:                    byte[] magic = Database.getMagic(textStorage);
0766:                    store = FileStore.open(null, fileName, "r", magic);
0767:                    long length = store.length();
0768:                    int offset = FileStore.HEADER_LENGTH;
0769:                    int blockSize = DiskFile.BLOCK_SIZE;
0770:                    int blocks = (int) (length / blockSize);
0771:                    blockCount = 1;
0772:                    int[] pageOwners = new int[blocks
0773:                            / DiskFile.BLOCKS_PER_PAGE];
0774:                    for (int block = 0; block < blocks; block += blockCount) {
0775:                        store.seek(offset + (long) block * blockSize);
0776:                        byte[] buff = new byte[blockSize];
0777:                        DataPage s = DataPage.create(this , buff);
0778:                        store.readFully(buff, 0, blockSize);
0779:                        blockCount = s.readInt();
0780:                        storageId = -1;
0781:                        recordLength = -1;
0782:                        valueId = -1;
0783:                        if (blockCount == 0) {
0784:                            // free block
0785:                            blockCount = 1;
0786:                            continue;
0787:                        } else if (blockCount < 0) {
0788:                            writeDataError(writer, "blockCount<0",
0789:                                    s.getBytes(), 1);
0790:                            blockCount = 1;
0791:                            continue;
0792:                        } else if ((blockCount * blockSize) >= Integer.MAX_VALUE / 4) {
0793:                            writeDataError(writer, "blockCount=" + blockCount,
0794:                                    s.getBytes(), 1);
0795:                            blockCount = 1;
0796:                            continue;
0797:                        }
0798:                        writer.println("-- block " + block + " - "
0799:                                + (block + blockCount - 1));
0800:                        try {
0801:                            s.checkCapacity(blockCount * blockSize);
0802:                        } catch (OutOfMemoryError e) {
0803:                            writeDataError(writer, "out of memory", s
0804:                                    .getBytes(), 1);
0805:                            blockCount = 1;
0806:                            continue;
0807:                        }
0808:                        if (blockCount > 1) {
0809:                            if ((blockCount * blockSize) < 0) {
0810:                                writeDataError(writer, "wrong blockCount", s
0811:                                        .getBytes(), 1);
0812:                                blockCount = 1;
0813:                            } else {
0814:                                store.readFully(s.getBytes(), blockSize,
0815:                                        blockCount * blockSize - blockSize);
0816:                            }
0817:                        }
0818:                        try {
0819:                            s.check(blockCount * blockSize);
0820:                        } catch (SQLException e) {
0821:                            writeDataError(writer, "wrong checksum", s
0822:                                    .getBytes(), 1);
0823:                            blockCount = 1;
0824:                            continue;
0825:                        }
0826:                        storageId = s.readInt();
0827:                        if (storageId < 0) {
0828:                            writeDataError(writer, "storageId<0", s.getBytes(),
0829:                                    blockCount);
0830:                            continue;
0831:                        }
0832:                        int page = block / DiskFile.BLOCKS_PER_PAGE;
0833:                        if (pageOwners[page] != 0
0834:                                && pageOwners[page] != storageId) {
0835:                            writeDataError(writer,
0836:                                    "double allocation, previous="
0837:                                            + pageOwners[page] + " now="
0838:                                            + storageId, s.getBytes(),
0839:                                    blockCount);
0840:                        } else {
0841:                            pageOwners[page] = storageId;
0842:                        }
0843:                        recordLength = s.readInt();
0844:                        if (recordLength <= 0) {
0845:                            writeDataError(writer, "recordLength<0", s
0846:                                    .getBytes(), blockCount);
0847:                            continue;
0848:                        }
0849:                        Value[] data;
0850:                        try {
0851:                            data = new Value[recordLength];
0852:                        } catch (OutOfMemoryError e) {
0853:                            writeDataError(writer, "out of memory", s
0854:                                    .getBytes(), blockCount);
0855:                            continue;
0856:                        }
0857:                        if (!objectIdSet.contains(ObjectUtils
0858:                                .getInteger(storageId))) {
0859:                            objectIdSet.add(ObjectUtils.getInteger(storageId));
0860:                            StringBuffer sb = new StringBuffer();
0861:                            sb.append("CREATE TABLE O_" + storageId + "(");
0862:                            for (int i = 0; i < recordLength; i++) {
0863:                                if (i > 0) {
0864:                                    sb.append(", ");
0865:                                }
0866:                                sb.append("C");
0867:                                sb.append(i);
0868:                                sb.append(" VARCHAR");
0869:                            }
0870:                            sb.append(");");
0871:                            writer.println(sb.toString());
0872:                            writer.flush();
0873:                        }
0874:                        StringBuffer sb = new StringBuffer();
0875:                        sb.append("INSERT INTO O_" + storageId + " VALUES(");
0876:                        for (valueId = 0; valueId < recordLength; valueId++) {
0877:                            try {
0878:                                Value v = s.readValue();
0879:                                data[valueId] = v;
0880:                                if (valueId > 0) {
0881:                                    sb.append(", ");
0882:                                }
0883:                                sb.append(getSQL(v));
0884:                            } catch (Exception e) {
0885:                                writeDataError(writer, "exception " + e, s
0886:                                        .getBytes(), blockCount);
0887:                                continue;
0888:                            } catch (OutOfMemoryError e) {
0889:                                writeDataError(writer, "out of memory", s
0890:                                        .getBytes(), blockCount);
0891:                                continue;
0892:                            }
0893:                        }
0894:                        sb.append(");");
0895:                        writer.println(sb.toString());
0896:                        writer.flush();
0897:                        if (storageId == 0) {
0898:                            try {
0899:                                SimpleRow r = new SimpleRow(data);
0900:                                MetaRecord meta = new MetaRecord(r);
0901:                                schema.add(meta);
0902:                                if (meta.getObjectType() == DbObject.TABLE_OR_VIEW) {
0903:                                    String sql = data[3].getString();
0904:                                    int end = sql.indexOf('(');
0905:                                    if (end >= 0) {
0906:                                        int start = sql.lastIndexOf(' ', end);
0907:                                        String name = sql.substring(start, end)
0908:                                                .trim();
0909:                                        tableMap
0910:                                                .put(ObjectUtils
0911:                                                        .getInteger(meta
0912:                                                                .getId()), name);
0913:                                    }
0914:                                }
0915:                            } catch (Throwable t) {
0916:                                writeError(writer, t);
0917:                            }
0918:                        }
0919:                    }
0920:                    MetaRecord.sort(schema);
0921:                    for (int i = 0; i < schema.size(); i++) {
0922:                        MetaRecord m = (MetaRecord) schema.get(i);
0923:                        writer.println(m.getSQL() + ";");
0924:                    }
0925:                    for (Iterator it = tableMap.entrySet().iterator(); it
0926:                            .hasNext();) {
0927:                        Map.Entry entry = (Entry) it.next();
0928:                        Integer objectId = (Integer) entry.getKey();
0929:                        String name = (String) entry.getValue();
0930:                        writer.println("INSERT INTO " + name
0931:                                + " SELECT * FROM O_" + objectId + ";");
0932:                    }
0933:                    for (Iterator it = objectIdSet.iterator(); it.hasNext();) {
0934:                        Integer objectId = (Integer) it.next();
0935:                        writer.println("DROP TABLE O_" + objectId + ";");
0936:                    }
0937:                    writer.println("DROP ALIAS READ_CLOB;");
0938:                    writer.println("DROP ALIAS READ_BLOB;");
0939:                    writer.close();
0940:                } catch (Throwable e) {
0941:                    writeError(writer, e);
0942:                } finally {
0943:                    IOUtils.closeSilently(writer);
0944:                    closeSilently(store);
0945:                }
0946:            }
0947:
0948:            private void closeSilently(FileStore store) {
0949:                if (store != null) {
0950:                    store.closeSilently();
0951:                    store = null;
0952:                }
0953:            }
0954:
0955:            private void writeError(PrintWriter writer, Throwable e) {
0956:                if (writer != null) {
0957:                    writer.println("// error: " + e);
0958:                }
0959:                logError("Error", e);
0960:            }
0961:
0962:            /**
0963:             * INTERNAL
0964:             */
0965:            public boolean getTextStorage() {
0966:                return textStorage;
0967:            }
0968:
0969:            /**
0970:             * INTERNAL
0971:             */
0972:            public String getDatabasePath() {
0973:                return databaseName;
0974:            }
0975:
0976:            /**
0977:             * INTERNAL
0978:             */
0979:            public FileStore openFile(String name, String mode,
0980:                    boolean mustExist) throws SQLException {
0981:                return FileStore.open(this , name, "rw",
0982:                        Constants.MAGIC_FILE_HEADER.getBytes());
0983:            }
0984:
0985:            /**
0986:             * INTERNAL
0987:             */
0988:            public int getChecksum(byte[] data, int start, int end) {
0989:                int x = 0;
0990:                while (start < end) {
0991:                    x += data[start++];
0992:                }
0993:                return x;
0994:            }
0995:
0996:            /**
0997:             * INTERNAL
0998:             */
0999:            public void checkPowerOff() throws SQLException {
1000:            }
1001:
1002:            /**
1003:             * INTERNAL
1004:             */
1005:            public void checkWritingAllowed() throws SQLException {
1006:            }
1007:
1008:            /**
1009:             * INTERNAL
1010:             */
1011:            public void freeUpDiskSpace() throws SQLException {
1012:            }
1013:
1014:            /**
1015:             * INTERNAL
1016:             */
1017:            public void handleInvalidChecksum() throws SQLException {
1018:                throw new SQLException("Invalid Checksum");
1019:            }
1020:
1021:            /**
1022:             * INTERNAL
1023:             */
1024:            public int compareTypeSave(Value a, Value b) throws SQLException {
1025:                throw Message.getInternalError();
1026:            }
1027:
1028:            /**
1029:             * INTERNAL
1030:             */
1031:            public int getMaxLengthInplaceLob() {
1032:                throw Message.getInternalError();
1033:            }
1034:
1035:            /**
1036:             * INTERNAL
1037:             */
1038:            public int allocateObjectId(boolean b, boolean c) {
1039:                throw Message.getInternalError();
1040:            }
1041:
1042:            /**
1043:             * INTERNAL
1044:             */
1045:            public String createTempFile() throws SQLException {
1046:                throw Message.getInternalError();
1047:            }
1048:
1049:            /**
1050:             * INTERNAL
1051:             */
1052:            public String getLobCompressionAlgorithm(int type) {
1053:                return null;
1054:            }
1055:
1056:            /**
1057:             * INTERNAL
1058:             */
1059:            public Object getLobSyncObject() {
1060:                return this ;
1061:            }
1062:
1063:            /**
1064:             * INTERNAL
1065:             */
1066:            public boolean getLobFilesInDirectories() {
1067:                return lobFilesInDirectories;
1068:            }
1069:
1070:            /**
1071:             * INTERNAL
1072:             */
1073:            public SmallLRUCache getLobFileListCache() {
1074:                return null;
1075:            }
1076:
1077:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.