⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesystemdatabase.java

📁 非常棒的java数据库
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
 * (http://h2database.com/html/license.html).
 * Initial Developer: H2 Group
 */
package org.h2.store.fs;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;

import org.h2.Driver;
import org.h2.message.Message;
import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils;

/**
 * This file system stores everything in a database.
 */
public class FileSystemDatabase extends FileSystem {

    private Connection conn;
    private String url;
    private static final HashMap INSTANCES = new HashMap();
    private HashMap preparedMap = new HashMap();
    private boolean log;

    public static synchronized FileSystem getInstance(String url) {
        int idx = url.indexOf('/');
        if (idx > 0) {
            url = url.substring(0, idx);
        }
        FileSystemDatabase fs = (FileSystemDatabase) INSTANCES.get(url);
        if (fs != null) {
            return fs;
        }
        Connection conn;
        try {
            if (url.startsWith("jdbc:h2:")) {
                // avoid using DriverManager if possible
                conn = Driver.load().connect(url, new Properties());
            } else {
                conn = JdbcUtils.getConnection(null, url, new Properties());
            }
            boolean log = url.toUpperCase().indexOf("TRACE_") >= 0;
            fs = new FileSystemDatabase(url, conn, log);
            INSTANCES.put(url, fs);
            return fs;
        } catch (SQLException e) {
            throw Message.convertToInternal(e);
        }
    }

    public void close() {
        JdbcUtils.closeSilently(conn);
    }

    private FileSystemDatabase(String url, Connection conn, boolean log) throws SQLException {
        this.url = url;
        this.conn = conn;
        this.log = log;
        Statement stat = conn.createStatement();
        conn.setAutoCommit(false);
        stat.execute("SET ALLOW_LITERALS NONE");
        stat.execute("CREATE TABLE IF NOT EXISTS FILES("
                + "ID IDENTITY, PARENTID BIGINT, NAME VARCHAR, "
                + "LASTMODIFIED BIGINT, LENGTH BIGINT, "
                + "UNIQUE(PARENTID, NAME))");
        stat.execute("CREATE TABLE IF NOT EXISTS FILEDATA("
                + "ID BIGINT PRIMARY KEY, DATA BLOB)");
        PreparedStatement prep = conn.prepareStatement("SET MAX_LENGTH_INPLACE_LOB ?");
        prep.setLong(1, 4096);
        prep.execute();
        stat.execute("MERGE INTO FILES VALUES(ZERO(), NULL, SPACE(ZERO()), ZERO(), NULL)");
        commit();
        if (log) {
            ResultSet rs = stat.executeQuery("SELECT * FROM FILES ORDER BY PARENTID, NAME");
            while (rs.next()) {
                long id = rs.getLong("ID");
                long parentId = rs.getLong("PARENTID");
                String name = rs.getString("NAME");
                long lastModified = rs.getLong("LASTMODIFIED");
                long length = rs.getLong("LENGTH");
                log(id + " " + name + " parent:" + parentId + " length:" + length + " lastMod:"
                        + lastModified);
            }
        }
    }

    private void commit() {
        try {
            conn.commit();
        } catch (SQLException e) {
            if (log) {
                e.printStackTrace();
            }
        }
    }

    private void rollback() {
        try {
            conn.rollback();
        } catch (SQLException e) {
            if (log) {
                e.printStackTrace();
            }
        }
    }

    private void log(String s) {
        if (log) {
            System.out.println(s);
        }
    }

    private long getId(String fileName, boolean parent) {
        fileName = translateFileName(fileName);
        log(fileName);
        try {
            String[] path = StringUtils.arraySplit(fileName, '/', false);
            long id = 0;
            int len = parent ? path.length - 1 : path.length;
            if (fileName.endsWith("/")) {
                len--;
            }
            for (int i = 1; i < len; i++) {
                PreparedStatement prep = prepare("SELECT ID FROM FILES WHERE PARENTID=? AND NAME=?");
                prep.setLong(1, id);
                prep.setString(2, path[i]);
                ResultSet rs = prep.executeQuery();
                if (!rs.next()) {
                    return -1;
                }
                id = rs.getLong(1);
            }
            return id;
        } catch (SQLException e) {
            throw convert(e);
        }
    }

    private String translateFileName(String fileName) {
        if (fileName.startsWith(url)) {
            fileName = fileName.substring(url.length());
        }
        return fileName;
    }

    private PreparedStatement prepare(String sql) throws SQLException {
        PreparedStatement prep = (PreparedStatement) preparedMap.get(sql);
        if (prep == null) {
            prep = conn.prepareStatement(sql);
            preparedMap.put(sql, prep);
        }
        return prep;
    }

    private RuntimeException convert(SQLException e) {
        if (log) {
            e.printStackTrace();
        }
        return new RuntimeException(e.toString());
    }

    public boolean canWrite(String fileName) {
        return true;
    }

    public void copy(String original, String copy) throws SQLException {
        try {
            OutputStream out = openFileOutputStream(copy, false);
            InputStream in = openFileInputStream(original);
            IOUtils.copyAndClose(in, out);
        } catch (IOException e) {
            rollback();
            throw Message.convertIOException(e, "Can not copy " + original + " to " + copy);
        }
    }

    public void createDirs(String fileName) throws SQLException {
        fileName = translateFileName(fileName);
        try {
            String[] path = StringUtils.arraySplit(fileName, '/', false);
            long parentId = 0;
            int len = path.length;
            if (fileName.endsWith("/")) {
                len--;
            }
            len--;
            for (int i = 1; i < len; i++) {
                PreparedStatement prep = prepare("SELECT ID FROM FILES WHERE PARENTID=? AND NAME=?");
                prep.setLong(1, parentId);
                prep.setString(2, path[i]);
                ResultSet rs = prep.executeQuery();
                if (!rs.next()) {
                    prep = prepare("INSERT INTO FILES(NAME, PARENTID, LASTMODIFIED) VALUES(?, ?, ?)");
                    prep.setString(1, path[i]);
                    prep.setLong(2, parentId);
                    prep.setLong(3, System.currentTimeMillis());
                    prep.execute();
                    rs = JdbcUtils.getGeneratedKeys(prep);
                    rs.next();
                    parentId = rs.getLong(1);
                } else {
                    parentId = rs.getLong(1);
                }
            }
            commit();
        } catch (SQLException e) {
            rollback();
            throw convert(e);
        }
    }

    public boolean createNewFile(String fileName) throws SQLException {
        try {
            if (exists(fileName)) {
                return false;
            }
            openFileObject(fileName, "rw").close();
            return true;
        } catch (IOException e) {
            throw Message.convert(e);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -