KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > server > ftp > FileSystemDatabase


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.server.ftp;
6
7 import java.io.IOException JavaDoc;
8 import java.io.InputStream JavaDoc;
9 import java.io.OutputStream JavaDoc;
10 import java.sql.Connection JavaDoc;
11 import java.sql.PreparedStatement JavaDoc;
12 import java.sql.ResultSet JavaDoc;
13 import java.sql.SQLException JavaDoc;
14 import java.sql.Statement JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.HashMap JavaDoc;
17
18 import org.h2.util.IOUtils;
19 import org.h2.util.JdbcUtils;
20 import org.h2.util.StringUtils;
21
22 public class FileSystemDatabase {
23     private Connection JavaDoc conn;
24     private HashMap JavaDoc preparedMap = new HashMap JavaDoc();
25     private boolean log;
26     
27     FileSystemDatabase(Connection JavaDoc conn, boolean log) throws SQLException JavaDoc {
28         this.conn = conn;
29         this.log = log;
30         Statement JavaDoc stat = conn.createStatement();
31         conn.setAutoCommit(false);
32         stat.execute("SET ALLOW_LITERALS NONE");
33         stat.execute("CREATE TABLE IF NOT EXISTS FILES(" +
34                 "ID IDENTITY, PARENTID BIGINT, NAME VARCHAR, " +
35                 "LASTMODIFIED BIGINT, LENGTH BIGINT, "+
36                 "UNIQUE(PARENTID, NAME))");
37         stat.execute("CREATE TABLE IF NOT EXISTS FILEDATA(" +
38                 "ID BIGINT PRIMARY KEY, DATA BLOB)");
39         PreparedStatement JavaDoc prep = conn.prepareStatement("SET MAX_LENGTH_INPLACE_LOB ?");
40         prep.setLong(1, 4096);
41         prep.execute();
42         commit();
43         if(log) {
44             ResultSet JavaDoc rs = stat.executeQuery(
45                     "SELECT * FROM FILES ORDER BY PARENTID, NAME");
46             while(rs.next()) {
47                 long id = rs.getLong("ID");
48                 long parentId = rs.getLong("PARENTID");
49                 String JavaDoc name = rs.getString("NAME");
50                 long lastModified = rs.getLong("LASTMODIFIED");
51                 long length = rs.getLong("LENGTH");
52                 System.out.println(id + " " + name + " parent:"+parentId+" length:" + length + " lastMod:" + lastModified);
53             }
54         }
55     }
56
57     synchronized void delete(String JavaDoc fullName) {
58         try {
59             long id = getId(fullName, false);
60             PreparedStatement JavaDoc prep = prepare("DELETE FROM FILES WHERE ID=?");
61             prep.setLong(1, id);
62             prep.execute();
63             prep = prepare("DELETE FROM FILEDATA WHERE ID=?");
64             prep.setLong(1, id);
65             prep.execute();
66             commit();
67         } catch(SQLException JavaDoc e) {
68             rollback();
69             throw convert(e);
70         }
71     }
72     
73     synchronized boolean exists(String JavaDoc fullName) {
74         long id = getId(fullName, false);
75         return id >= 0;
76     }
77
78     synchronized void read(String JavaDoc fullName, long skip, OutputStream JavaDoc out) throws IOException JavaDoc {
79         try {
80             long id = getId(fullName, false);
81             PreparedStatement JavaDoc prep = prepare("SELECT DATA FROM FILEDATA WHERE ID=?");
82             prep.setLong(1, id);
83             ResultSet JavaDoc rs = prep.executeQuery();
84             if(rs.next()) {
85                 InputStream JavaDoc in = rs.getBinaryStream(1);
86                 IOUtils.skipFully(in, skip);
87                 IOUtils.copyAndClose(in, out);
88             }
89         } catch(SQLException JavaDoc e) {
90             throw convert(e);
91         }
92     }
93     
94     synchronized void write(String JavaDoc fullName, InputStream JavaDoc in) throws IOException JavaDoc {
95         try {
96             long id = getId(fullName, false);
97             if(id >= 0) {
98                 PreparedStatement JavaDoc prep = prepare("DELETE FROM FILES WHERE ID=?");
99                 prep.setLong(1, id);
100                 prep.execute();
101                 prep = prepare("DELETE FROM FILEDATA WHERE ID=?");
102                 prep.setLong(1, id);
103                 prep.execute();
104             }
105             long parentId = getId(fullName, true);
106             PreparedStatement JavaDoc prep = prepare("INSERT INTO FILES(PARENTID, NAME, LASTMODIFIED) VALUES(?, ?, ?)");
107             prep.setLong(1, parentId);
108             prep.setString(2, getName(fullName));
109             prep.setLong(3, System.currentTimeMillis());
110             prep.execute();
111             ResultSet JavaDoc rs = JdbcUtils.getGeneratedKeys(prep);
112             rs.next();
113             id = rs.getLong(1);
114             prep = prepare("INSERT INTO FILEDATA(ID, DATA) VALUES(?, ?)");
115             prep.setLong(1, id);
116             prep.setBinaryStream(2, in, -1);
117             in.close();
118             prep.execute();
119             prep = prepare("UPDATE FILES SET LENGTH=(SELECT LENGTH(DATA) FROM FILEDATA WHERE ID=?) WHERE ID=?");
120             prep.setLong(1, id);
121             prep.setLong(2, id);
122             prep.execute();
123             commit();
124         } catch(SQLException JavaDoc e) {
125             rollback();
126             throw convert(e);
127         }
128     }
129
130     synchronized boolean isDirectory(String JavaDoc fullName) {
131         try {
132             long id = getId(fullName, false);
133             PreparedStatement JavaDoc prep = prepare("SELECT LENGTH FROM FILES WHERE ID=?");
134             prep.setLong(1, id);
135             ResultSet JavaDoc rs = prep.executeQuery();
136             rs.next();
137             rs.getLong(1);
138             return rs.wasNull();
139         } catch(SQLException JavaDoc e) {
140             throw convert(e);
141         }
142     }
143
144     synchronized long lastModified(String JavaDoc fullName) {
145         try {
146             long id = getId(fullName, false);
147             PreparedStatement JavaDoc prep = prepare("SELECT LASTMODIFIED FROM FILES WHERE ID=?");
148             prep.setLong(1, id);
149             ResultSet JavaDoc rs = prep.executeQuery();
150             rs.next();
151             return rs.getLong(1);
152         } catch(SQLException JavaDoc e) {
153             throw convert(e);
154         }
155     }
156
157     synchronized long length(String JavaDoc fullName) {
158         try {
159             long id = getId(fullName, false);
160             PreparedStatement JavaDoc prep = prepare("SELECT LENGTH FROM FILES WHERE ID=?");
161             prep.setLong(1, id);
162             ResultSet JavaDoc rs = prep.executeQuery();
163             rs.next();
164             return rs.getLong(1);
165         } catch(SQLException JavaDoc e) {
166             throw convert(e);
167         }
168     }
169
170     synchronized FileObject[] listFiles(String JavaDoc fullName) {
171         try {
172             String JavaDoc name = fullName;
173             if(!name.endsWith("/")) {
174                 name += "/";
175             }
176             long id = getId(fullName, false);
177             PreparedStatement JavaDoc prep = prepare("SELECT NAME FROM FILES WHERE PARENTID=? ORDER BY NAME");
178             prep.setLong(1, id);
179             ResultSet JavaDoc rs = prep.executeQuery();
180             ArrayList JavaDoc list = new ArrayList JavaDoc();
181             while(rs.next()) {
182                 FileObject f = FileObjectDatabase.get(this, name + rs.getString(1));
183                 list.add(f);
184             }
185             FileObject[] result = new FileObject[list.size()];
186             list.toArray(result);
187             return result;
188         } catch(SQLException JavaDoc e) {
189             throw convert(e);
190         }
191     }
192     
193     String JavaDoc getName(String JavaDoc fullName) {
194         String JavaDoc[] path = StringUtils.arraySplit(fullName, '/', false);
195         return path[path.length-1];
196     }
197     
198     private long getId(String JavaDoc fullName, boolean parent) {
199         try {
200             String JavaDoc[] path = StringUtils.arraySplit(fullName, '/', false);
201             long id = 0;
202             int len = parent ? path.length-1 : path.length;
203             if(fullName.endsWith("/")) {
204                 len--;
205             }
206             for(int i=0; i<len; i++) {
207                 PreparedStatement JavaDoc prep = prepare("SELECT ID FROM FILES WHERE PARENTID=? AND NAME=?");
208                 prep.setLong(1, id);
209                 prep.setString(2, path[i]);
210                 ResultSet JavaDoc rs = prep.executeQuery();
211                 if(!rs.next()) {
212                     return -1;
213                 }
214                 id = rs.getLong(1);
215             }
216             return id;
217         } catch(SQLException JavaDoc e) {
218             throw convert(e);
219         }
220     }
221
222     synchronized void mkdirs(String JavaDoc fullName) {
223         try {
224             String JavaDoc[] path = StringUtils.arraySplit(fullName, '/', false);
225             long parentId = 0;
226             int len = path.length;
227             if(fullName.endsWith("/")) {
228                 len--;
229             }
230             for(int i=0; i<len; i++) {
231                 PreparedStatement JavaDoc prep = prepare("SELECT ID FROM FILES WHERE PARENTID=? AND NAME=?");
232                 prep.setLong(1, parentId);
233                 prep.setString(2, path[i]);
234                 ResultSet JavaDoc rs = prep.executeQuery();
235                 if(!rs.next()) {
236                     prep = prepare("INSERT INTO FILES(NAME, PARENTID, LASTMODIFIED) VALUES(?, ?, ?)");
237                     prep.setString(1, path[i]);
238                     prep.setLong(2, parentId);
239                     prep.setLong(3, System.currentTimeMillis());
240                     prep.execute();
241                     rs = JdbcUtils.getGeneratedKeys(prep);
242                     rs.next();
243                     parentId = rs.getLong(1);
244                 } else {
245                     parentId = rs.getLong(1);
246                 }
247             }
248             commit();
249         } catch(SQLException JavaDoc e) {
250             rollback();
251             throw convert(e);
252         }
253     }
254
255     synchronized boolean renameTo(String JavaDoc oldFullName, String JavaDoc newFullName) {
256         try {
257             long parentOld = getId(oldFullName, true);
258             long parentNew = getId(newFullName, true);
259             if(parentOld != parentNew) {
260                 return false;
261             }
262             String JavaDoc newName = getName(newFullName);
263             long id = getId(oldFullName, false);
264             PreparedStatement JavaDoc prep = prepare("UPDATE FILES SET NAME=? WHERE ID=?");
265             prep.setString(1, newName);
266             prep.setLong(2, id);
267             prep.execute();
268             commit();
269             return true;
270         } catch(SQLException JavaDoc e) {
271             rollback();
272             throw convert(e);
273         }
274     }
275
276     private RuntimeException JavaDoc convert(SQLException JavaDoc e) {
277         if(log) {
278             e.printStackTrace();
279         }
280         return new RuntimeException JavaDoc(e.toString());
281     }
282     
283     private PreparedStatement JavaDoc prepare(String JavaDoc sql) throws SQLException JavaDoc {
284         PreparedStatement JavaDoc prep = (PreparedStatement JavaDoc) preparedMap.get(sql);
285         if(prep == null) {
286             prep = conn.prepareStatement(sql);
287             preparedMap.put(sql, prep);
288         }
289         return prep;
290     }
291     
292     private void commit() {
293         try {
294             conn.commit();
295         } catch(SQLException JavaDoc e) {
296             if(log) {
297                 e.printStackTrace();
298             }
299         }
300     }
301     
302     private void rollback() {
303         try {
304             conn.rollback();
305         } catch(SQLException JavaDoc e) {
306             if(log) {
307                 e.printStackTrace();
308             }
309         }
310     }
311
312 }
313
Popular Tags